Power System Platform  2026w10a-beta
Loading...
Searching...
No Matches
Limiter.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 "Limiter.h"
19#include "../../forms/LimiterForm.h"
20#include <wx/pen.h>
21#include <wx/brush.h>
22
23Limiter::Limiter(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
35Limiter::~Limiter()
36{
37 for (auto& node : m_nodeList) if (node) delete node;
38 m_nodeList.clear();
39}
40
41//void Limiter::Draw(wxPoint2DDouble translation, double scale) const
42//{
43// glLineWidth(1.0);
44// if(m_selected) {
45// glColor4dv(m_selectionColour.GetRGBA());
46// double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
47// DrawRectangle(m_position, m_width + borderSize, m_height + borderSize);
48// }
49// glColor4d(1.0, 1.0, 1.0, 1.0);
50// DrawRectangle(m_position, m_width, m_height);
51// glColor4d(0.0, 0.0, 0.0, 1.0);
52// DrawRectangle(m_position, m_width, m_height, GL_LINE_LOOP);
53//
54// // Plot symbol.
55// glLineWidth(2.0);
56// std::vector<wxPoint2DDouble> limSymbol;
57// limSymbol.push_back(m_position + wxPoint2DDouble(10, -10));
58// limSymbol.push_back(m_position + wxPoint2DDouble(2, -10));
59// limSymbol.push_back(m_position + wxPoint2DDouble(-2, 10));
60// limSymbol.push_back(m_position + wxPoint2DDouble(-10, 10));
61// glColor4d(0.0, 0.3, 1.0, 1.0);
62// DrawLine(limSymbol);
63//
64// glColor4d(0.0, 0.0, 0.0, 1.0);
65// DrawNodes();
66//}
67
68void Limiter::DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext* gc) const
69{
70 if (m_selected) {
71 gc->SetPen(*wxTRANSPARENT_PEN);
72 gc->SetBrush(wxBrush(m_selectionColour));
73 double borderSize = (m_borderSize * 2.0 + 1.0) / scale;
74 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);
75 }
76 gc->SetPen(wxPen(wxColour(0, 0, 0, 255), 1));
77 gc->SetBrush(wxBrush(wxColour(255, 255, 255, 255)));
78 gc->DrawRectangle(m_position.m_x - m_width / 2, m_position.m_y - m_height / 2, m_width, m_height);
79
80 // Plot symbol.
81 gc->SetPen(wxPen(wxColour(0, 77, 255, 255), 2));
82 gc->SetBrush(*wxTRANSPARENT_BRUSH);
83 wxPoint2DDouble limSymbol[4];
84 limSymbol[0] = m_position + wxPoint2DDouble(10, -10);
85 limSymbol[1] = m_position + wxPoint2DDouble(2, -10);
86 limSymbol[2] = m_position + wxPoint2DDouble(-2, 10);
87 limSymbol[3] = m_position + wxPoint2DDouble(-10, 10);
88 gc->StrokeLines(4, limSymbol);
89
90 gc->SetPen(*wxTRANSPARENT_PEN);
91 gc->SetBrush(*wxBLACK_BRUSH);
92 DrawDCNodes(gc);
93}
94
95bool Limiter::ShowForm(wxWindow* parent, Element* element)
96{
97 LimiterForm limiter(parent, this);
98 limiter.CenterOnParent();
99 if (limiter.ShowModal() == wxID_OK) {
100 return true;
101 }
102 return false;
103}
104
105void Limiter::Rotate(bool clockwise)
106{
107 if (clockwise)
108 m_angle += 90.0;
109 else
110 m_angle -= 90.0;
111 if (m_angle >= 360.0)
112 m_angle = 0.0;
113 else if (m_angle < 0)
114 m_angle = 270.0;
115
116 UpdatePoints();
117
118 for (auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
119 Node* node = *it;
120 node->Rotate(clockwise);
121 }
122}
123
124void Limiter::UpdatePoints()
125{
126 if (m_angle == 0.0) {
127 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
128 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(18, 0));
129 }
130 else if (m_angle == 90.0) {
131 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, -18));
132 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, 18));
133 }
134 else if (m_angle == 180.0) {
135 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(18, 0));
136 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(-18, 0));
137 }
138 else if (m_angle == 270.0) {
139 m_nodeList[0]->SetPosition(m_position + wxPoint2DDouble(0, 18));
140 m_nodeList[1]->SetPosition(m_position + wxPoint2DDouble(0, -18));
141 }
142}
143
144bool Limiter::Solve(double* input, double timeStep)
145{
146 if (!input) {
147 m_output = 0.0;
148 return true;
149 }
150 m_output = input[0];
151 if (m_output > m_upLimit)
152 m_output = m_upLimit;
153 else if (m_output < m_lowLimit)
154 m_output = m_lowLimit;
155
156 return true;
157}
158
160{
161 Limiter* copy = new Limiter(m_elementID);
162 *copy = *this;
163 return copy;
164}
165
166rapidxml::xml_node<>* Limiter::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
167{
168 auto elementNode = XMLParser::AppendNode(doc, elementListNode, "Limiter");
169 XMLParser::SetNodeAttribute(doc, elementNode, "ID", m_elementID);
170
171 SaveCADProperties(doc, elementNode);
172 SaveControlNodes(doc, elementNode);
173
174 // Element properties
175 auto upLimit = XMLParser::AppendNode(doc, elementNode, "UpperLimit");
176 XMLParser::SetNodeValue(doc, upLimit, m_upLimit);
177 auto lowLimit = XMLParser::AppendNode(doc, elementNode, "LowerLimit");
178 XMLParser::SetNodeValue(doc, lowLimit, m_lowLimit);
179
180 return elementNode;
181}
182
183bool Limiter::OpenElement(rapidxml::xml_node<>* elementNode)
184{
185 if (!OpenCADProperties(elementNode)) return false;
186 if (!OpenControlNodes(elementNode)) return false;
187
188 // Element properties
189 m_upLimit = XMLParser::GetNodeValueDouble(elementNode, "UpperLimit");
190 m_lowLimit = XMLParser::GetNodeValueDouble(elementNode, "LowerLimit");
191
192 StartMove(m_position);
193 UpdatePoints();
194 return true;
195}
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 limit control data.
Definition LimiterForm.h:32
Limits the input value by superior and inferior values.
Definition Limiter.h:33
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
Definition Limiter.cpp:95
virtual Element * GetCopy()
Get a the element copy.
Definition Limiter.cpp:159
virtual void Rotate(bool clockwise=true)
Rotate the element.
Definition Limiter.cpp:105
virtual void DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
Definition Limiter.cpp:68
Node of a control element. This class manages the user interaction with the connection and control el...