Power System Platform  2026w23a-beta
Loading...
Searching...
No Matches
Exponential.cpp
1/*
2 * Copyright (C) 2017 Thales Lima Oliveira <thales@ufu.br>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18#include "Exponential.h"
19#include "../../forms/ExponentialForm.h"
20#include <wx/pen.h>
21#include <wx/brush.h>
22
23Exponential::Exponential(int id) : ControlElement(id)
24{
25 m_width = m_height = 36.0;
26 Node* nodeIn = new Node(m_position + wxPoint2DDouble(-18, 0), Node::NodeType::NODE_IN, m_borderSize);
27 nodeIn->StartMove(m_position);
28 Node* nodeOut = new Node(m_position + wxPoint2DDouble(18, 0), Node::NodeType::NODE_OUT, m_borderSize);
29 nodeOut->SetAngle(180.0);
30 nodeOut->StartMove(m_position);
31 m_nodeList.push_back(nodeIn);
32 m_nodeList.push_back(nodeOut);
33}
34
35Exponential::~Exponential()
36{
37 for (auto& node : m_nodeList) if (node) delete node;
38 m_nodeList.clear();
39}
40
41void Exponential::DrawDC(GUIColour* guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
42{
43 if (m_selected) {
44 gc->SetPen(*wxTRANSPARENT_PEN);
45 gc->SetBrush(wxBrush(guiColour->selection));
46 double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
47 gc->DrawRectangle(m_position.m_x - m_width / 2 - borderSize / 2, m_position.m_y - m_height / 2 - borderSize / 2, m_width + borderSize, m_height + borderSize);
48 }
49 gc->SetPen(guiColour->enabled);
50 gc->SetBrush(guiColour->background);
51 //DrawRectangle(m_position, m_width, m_height);
52 gc->DrawRectangle(m_position.m_x - m_width / 2, m_position.m_y - m_height / 2, m_width, m_height);
53
54 // Plot symbol.
55 wxPoint2DDouble axis[4];
56 axis[0] = m_position + wxPoint2DDouble(-13, 13);
57 axis[1] = m_position + wxPoint2DDouble(13, 13);
58 axis[2] = m_position + wxPoint2DDouble(-13, -13);
59 axis[3] = m_position + wxPoint2DDouble(-13, 13);
60 gc->StrokeLines(2, &axis[0]);
61 gc->StrokeLines(2, &axis[2]);
62
63 gc->SetPen(wxPen(guiColour->bus, 2));
64 gc->SetBrush(*wxTRANSPARENT_BRUSH);
65 wxPoint2DDouble expSymbol[9];
66 expSymbol[0] = m_position + wxPoint2DDouble(-13, 13);
67 expSymbol[1] = m_position + wxPoint2DDouble(-6, 13);
68 expSymbol[2] = m_position + wxPoint2DDouble(2, 12);
69 expSymbol[3] = m_position + wxPoint2DDouble(4, 11);
70 expSymbol[4] = m_position + wxPoint2DDouble(6, 10);
71 expSymbol[5] = m_position + wxPoint2DDouble(8, 7);
72 expSymbol[6] = m_position + wxPoint2DDouble(11, -1);
73 expSymbol[7] = m_position + wxPoint2DDouble(12, -7);
74 expSymbol[8] = m_position + wxPoint2DDouble(13, -13);
75 gc->StrokeLines(9, expSymbol);
76
77 gc->SetPen(*wxTRANSPARENT_PEN);
78 gc->SetBrush(guiColour->enabled);
79 DrawDCNodes(gc);
80}
81
82bool Exponential::ShowForm(wxWindow* parent, Element* element, wxWindow* workspace)
83{
84 ExponentialForm form(parent, this);
85 form.CenterOnParent();
86 if (form.ShowModal() == wxID_OK) {
87 return true;
88 }
89 return false;
90}
91
92void Exponential::Rotate(bool clockwise)
93{
94 if (clockwise)
95 m_angle += 90.0;
96 else
97 m_angle -= 90.0;
98 if (m_angle >= 360.0)
99 m_angle = 0.0;
100 else if (m_angle < 0)
101 m_angle = 270.0;
102
103 UpdatePoints();
104
105 for (auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
106 Node* node = *it;
107 node->Rotate(clockwise);
108 }
109}
110
111void Exponential::UpdatePoints()
112{
113 if (m_angle == 0.0) {
114 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
115 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(18, 0));
116 }
117 else if (m_angle == 90.0) {
118 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -18));
119 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, 18));
120 }
121 else if (m_angle == 180.0) {
122 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(18, 0));
123 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
124 }
125 else if (m_angle == 270.0) {
126 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, 18));
127 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -18));
128 }
129}
130
131void Exponential::GetValues(double& aValue, double& bValue)
132{
133 aValue = m_aValue;
134 bValue = m_bValue;
135}
136
137void Exponential::SetValues(double aValue, double bValue)
138{
139 m_aValue = aValue;
140 m_bValue = bValue;
141}
142
143bool Exponential::Solve(double* input, double timeStep)
144{
145 if (!input) {
146 m_output = 0.0;
147 return true;
148 }
149 m_output = m_aValue * std::exp(m_bValue * input[0]);
150 return true;
151}
152
154{
155 Exponential* copy = new Exponential(*this);
156 return copy;
157}
158
159rapidxml::xml_node<>* Exponential::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
160{
161 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Exponential");
162 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
163
164 SaveCADProperties(doc, elementNode);
165 SaveControlNodes(doc, elementNode);
166
167 auto value = XMLParser::AppendNode(doc, elementNode, "Value");
168 auto aValue = XMLParser::AppendNode(doc, value, "A");
169 XMLParser::SetNodeValue(doc, aValue, m_aValue);
170 auto bValue = XMLParser::AppendNode(doc, value, "B");
171 XMLParser::SetNodeValue(doc, bValue, m_bValue);
172
173 return elementNode;
174}
175
176bool Exponential::OpenElement(rapidxml::xml_node<>* elementNode)
177{
178 if (!OpenCADProperties(elementNode)) return false;
179 if (!OpenControlNodes(elementNode)) return false;
180
181 // Element properties
182 auto value = elementNode->first_node("Value");
183 m_aValue = XMLParser::GetNodeValueDouble(value, "A");
184 m_bValue = XMLParser::GetNodeValueDouble(value, "B");
185
186 StartMove(m_position);
187 UpdatePoints();
188 return true;
189}
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:114
Form to edit the exponential control data.
Generates an output following an exponential function.
Definition Exponential.h:33
virtual void Rotate(bool clockwise=true)
Rotate the element.
virtual void DrawDC(GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
virtual bool Solve(double *input, double timeStep)
Calculates the exponential.
virtual bool ShowForm(wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
Show element data form.
virtual Element * GetCopy()
Get a the element copy.
Node of a control element. This class manages the user interaction with the connection and control el...