Power System Platform  2026w10a-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//void Exponential::Draw(wxPoint2DDouble translation, double scale) const
41//{
42// glLineWidth(1.0);
43// if(m_selected) {
44// glColor4dv(m_selectionColour.GetRGBA());
45// double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
46// DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
47// }
48// glColor4d(1.0, 1.0, 1.0, 1.0);
49// DrawRectangle(m_position, m_width, m_height);
50// glColor4d(0.0, 0.0, 0.0, 1.0);
51// DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
52//
53// // Plot symbol.
54// std::vector<wxPoint2DDouble> axis;
55// axis.push_back(m_position + wxPoint2DDouble(-13, 13));
56// axis.push_back(m_position + wxPoint2DDouble(13, 13));
57// axis.push_back(m_position + wxPoint2DDouble(-13, -13));
58// axis.push_back(m_position + wxPoint2DDouble(-13, 13));
59// DrawLine(axis, GL_LINES);
60//
61// glLineWidth(2.0);
62// std::vector<wxPoint2DDouble> expSymbol;
63// expSymbol.push_back(m_position + wxPoint2DDouble(-13, 13));
64// expSymbol.push_back(m_position + wxPoint2DDouble(-6, 13));
65// expSymbol.push_back(m_position + wxPoint2DDouble(2, 12));
66// expSymbol.push_back(m_position + wxPoint2DDouble(4, 11));
67// expSymbol.push_back(m_position + wxPoint2DDouble(6, 10));
68// expSymbol.push_back(m_position + wxPoint2DDouble(8, 7));
69// expSymbol.push_back(m_position + wxPoint2DDouble(11, -1));
70// expSymbol.push_back(m_position + wxPoint2DDouble(12, -7));
71// expSymbol.push_back(m_position + wxPoint2DDouble(13, -13));
72// glColor4d(0.0, 0.3, 1.0, 1.0);
73// DrawLine(expSymbol);
74//
75// glColor4d(0.0, 0.0, 0.0, 1.0);
76// DrawNodes();
77//}
78
79void Exponential::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
80{
81 if (m_selected) {
82 gc->SetPen(*wxTRANSPARENT_PEN);
83 gc->SetBrush(wxBrush(m_selectionColour));
84 double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
85 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);
86 }
87 gc->SetPen(*wxBLACK_PEN);
88 gc->SetBrush(*wxWHITE_BRUSH);
89 //DrawRectangle(m_position, m_width, m_height);
90 gc->DrawRectangle(m_position.m_x - m_width / 2, m_position.m_y - m_height / 2, m_width, m_height);
91
92 // Plot symbol.
93 wxPoint2DDouble axis[4];
94 axis[0] = m_position + wxPoint2DDouble(-13, 13);
95 axis[1] = m_position + wxPoint2DDouble(13, 13);
96 axis[2] = m_position + wxPoint2DDouble(-13, -13);
97 axis[3] = m_position + wxPoint2DDouble(-13, 13);
98 gc->StrokeLines(2, &axis[0]);
99 gc->StrokeLines(2, &axis[2]);
100
101 gc->SetPen(wxPen(wxColour(0, 77, 255, 255), 2));
102 gc->SetBrush(*wxTRANSPARENT_BRUSH);
103 wxPoint2DDouble expSymbol[9];
104 expSymbol[0] = m_position + wxPoint2DDouble(-13, 13);
105 expSymbol[1] = m_position + wxPoint2DDouble(-6, 13);
106 expSymbol[2] = m_position + wxPoint2DDouble(2, 12);
107 expSymbol[3] = m_position + wxPoint2DDouble(4, 11);
108 expSymbol[4] = m_position + wxPoint2DDouble(6, 10);
109 expSymbol[5] = m_position + wxPoint2DDouble(8, 7);
110 expSymbol[6] = m_position + wxPoint2DDouble(11, -1);
111 expSymbol[7] = m_position + wxPoint2DDouble(12, -7);
112 expSymbol[8] = m_position + wxPoint2DDouble(13, -13);
113 gc->StrokeLines(9, expSymbol);
114
115 gc->SetPen(*wxTRANSPARENT_PEN);
116 gc->SetBrush(wxBrush(wxColour(0, 0, 0, 255)));
117 DrawDCNodes(gc);
118}
119
120bool Exponential::ShowForm(wxWindow* parent, Element* element)
121{
122 ExponentialForm form(parent, this);
123 form.CenterOnParent();
124 if (form.ShowModal() == wxID_OK) {
125 return true;
126 }
127 return false;
128}
129
130void Exponential::Rotate(bool clockwise)
131{
132 if (clockwise)
133 m_angle += 90.0;
134 else
135 m_angle -= 90.0;
136 if (m_angle >= 360.0)
137 m_angle = 0.0;
138 else if (m_angle < 0)
139 m_angle = 270.0;
140
141 UpdatePoints();
142
143 for (auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
144 Node* node = *it;
145 node->Rotate(clockwise);
146 }
147}
148
149void Exponential::UpdatePoints()
150{
151 if (m_angle == 0.0) {
152 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
153 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(18, 0));
154 }
155 else if (m_angle == 90.0) {
156 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -18));
157 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, 18));
158 }
159 else if (m_angle == 180.0) {
160 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(18, 0));
161 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
162 }
163 else if (m_angle == 270.0) {
164 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, 18));
165 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -18));
166 }
167}
168
169void Exponential::GetValues(double& aValue, double& bValue)
170{
171 aValue = m_aValue;
172 bValue = m_bValue;
173}
174
175void Exponential::SetValues(double aValue, double bValue)
176{
177 m_aValue = aValue;
178 m_bValue = bValue;
179}
180
181bool Exponential::Solve(double* input, double timeStep)
182{
183 if (!input) {
184 m_output = 0.0;
185 return true;
186 }
187 m_output = m_aValue * std::exp(m_bValue * input[0]);
188 return true;
189}
190
192{
193 Exponential* copy = new Exponential(m_elementID);
194 *copy = *this;
195 return copy;
196}
197
198rapidxml::xml_node<>* Exponential::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
199{
200 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Exponential");
201 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
202
203 SaveCADProperties(doc, elementNode);
204 SaveControlNodes(doc, elementNode);
205
206 auto value = XMLParser::AppendNode(doc, elementNode, "Value");
207 auto aValue = XMLParser::AppendNode(doc, value, "A");
208 XMLParser::SetNodeValue(doc, aValue, m_aValue);
209 auto bValue = XMLParser::AppendNode(doc, value, "B");
210 XMLParser::SetNodeValue(doc, bValue, m_bValue);
211
212 return elementNode;
213}
214
215bool Exponential::OpenElement(rapidxml::xml_node<>* elementNode)
216{
217 if (!OpenCADProperties(elementNode)) return false;
218 if (!OpenControlNodes(elementNode)) return false;
219
220 // Element properties
221 auto value = elementNode->first_node("Value");
222 m_aValue = XMLParser::GetNodeValueDouble(value, "A");
223 m_bValue = XMLParser::GetNodeValueDouble(value, "B");
224
225 StartMove(m_position);
226 UpdatePoints();
227 return true;
228}
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:112
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 bool Solve(double *input, double timeStep)
Calculates the exponential.
virtual Element * GetCopy()
Get a the element copy.
virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Node of a control element. This class manages the user interaction with the connection and control el...