3#include "../../forms/HarmCurrentForm.h"
5HarmCurrent::HarmCurrent() :
Shunt() {}
7HarmCurrent::~HarmCurrent() {}
9HarmCurrent::HarmCurrent(wxString name) :
Shunt() { m_electricalData.name = name; }
21 m_parentList.push_back(parent);
23 wxPoint2DDouble parentPt =
28 m_position = parentPt + wxPoint2DDouble(0.0, 100.0);
31 m_rect = wxRect2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0, m_width, m_height);
33 m_pointList.push_back(parentPt);
34 m_pointList.push_back(
GetSwitchPoint(parent, parentPt, m_position));
35 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -m_height / 2.0 - 10.0));
36 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -m_height / 2.0));
38 m_triangPts.push_back(wxPoint2DDouble(-5, -15));
39 m_triangPts.push_back(wxPoint2DDouble(5, -15));
40 m_triangPts.push_back(wxPoint2DDouble(0.0, -30.0));
44 wxRect2DDouble genRect(0, 0, 0, 0);
45 m_switchRect.push_back(genRect);
122 wxColour elementColour;
125 elementColour = m_dynamicEventColour;
127 elementColour = m_onlineElementColour;
130 elementColour = m_offlineElementColour;
133 std::vector<wxPoint2DDouble> arrowPts;
134 arrowPts.push_back(wxPoint2DDouble(m_position.m_x, m_position.m_y - m_height / 2.0));
135 arrowPts.push_back(arrowPts[0] + wxPoint2DDouble(0, 40));
139 gc->SetPen(wxPen(wxColour(m_selectionColour), 2 + m_borderSize * 2.0));
140 gc->SetBrush(*wxTRANSPARENT_BRUSH);
141 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
146 gc->Translate(m_position.m_x, m_position.m_y);
147 gc->Rotate(wxDegToRad(m_angle));
148 gc->Translate(-m_position.m_x, -m_position.m_y);
150 DrawDCGround(m_position + wxPoint2DDouble(0, 10.0), gc);
152 gc->SetPen(*wxTRANSPARENT_PEN);
153 gc->SetBrush(wxBrush(wxColour(m_selectionColour)));
155 DrawDCCircle(wxPoint2DDouble(m_position.m_x, m_position.m_y - m_height / 2.0 + 20),
156 20.0 + (m_borderSize + 1.5) / scale, 20, gc);
161 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
165 gc->SetPen(wxPen(wxColour(elementColour), 2));
166 gc->SetBrush(*wxTRANSPARENT_BRUSH);
167 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
170 gc->SetPen(*wxTRANSPARENT_PEN);
171 gc->SetBrush(wxBrush(wxColour(elementColour)));
176 std::vector<wxPoint2DDouble> triangPts;
177 for (
int i = 0; i < 3; i++) { triangPts.push_back(m_triangPts[i] + m_position); }
180 gc->Translate(m_position.m_x, m_position.m_y);
181 gc->Rotate(wxDegToRad(m_angle));
182 gc->Translate(-m_position.m_x, -m_position.m_y);
185 gc->SetPen(wxPen(wxColour(elementColour), 2));
186 gc->SetBrush(*wxWHITE_BRUSH);
187 DrawDCCircle(wxPoint2DDouble(m_position.m_x, m_position.m_y - m_height / 2.0 + 20), 20, 20, gc);
189 gc->SetPen(*wxTRANSPARENT_PEN);
190 gc->SetBrush(wxBrush(wxColour(elementColour)));
194 gc->SetPen(wxPen(wxColour(elementColour), 2));
195 gc->StrokeLines(arrowPts.size(), &arrowPts[0]);
196 DrawDCGround(m_position + wxPoint2DDouble(0, 10.0), gc);
204 wxColour elementColour;
207 elementColour = m_dynamicEventColour;
209 elementColour = m_onlineElementColour;
212 elementColour = m_offlineElementColour;
217 arrowPts[0] = RotateAround(wxPoint2DDouble(m_position.m_x, m_position.m_y - m_height / 2.0), m_position, m_angle);
218 arrowPts[1] = RotateAround(wxPoint2DDouble(m_position.m_x, m_position.m_y - m_height / 2.0) + wxPoint2DDouble(0, 40), m_position, m_angle);
220 std::vector<wxPoint> pointListInt;
221 for (
auto& pt : m_pointList) {
222 pointListInt.emplace_back(
static_cast<int>(pt.m_x),
static_cast<int>(pt.m_y));
227 dc.SetPen(wxPen(wxColour(m_selectionColour), 2 + m_borderSize * 2.0));
228 dc.SetBrush(*wxTRANSPARENT_BRUSH);
229 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
231 DrawDCGround(m_position + wxPoint2DDouble(0, 10.0), dc);
233 dc.SetPen(*wxTRANSPARENT_PEN);
234 dc.SetBrush(wxBrush(wxColour(m_selectionColour)));
236 p = RotateAround(wxPoint2DDouble(m_position.m_x, m_position.m_y - m_height / 2.0 + 20), m_position, m_angle);
237 DrawDCCircle(p, 20.0 + (m_borderSize + 1.5) / scale, dc);
240 DrawDCCircle(pointListInt[0], 5.0 + m_borderSize / scale, dc);
244 dc.SetPen(wxPen(wxColour(elementColour), 2));
245 dc.SetBrush(*wxTRANSPARENT_BRUSH);
246 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
249 dc.SetPen(*wxTRANSPARENT_PEN);
250 dc.SetBrush(wxBrush(wxColour(elementColour)));
255 wxPoint triangPts[3];
258 for (
int i = 0; i < 3; i++) {
259 p = m_triangPts[i] + m_position;
260 triangPts[i] = RotateAround(p, m_position, m_angle);
263 dc.SetPen(wxPen(wxColour(elementColour), 2));
264 dc.SetBrush(*wxWHITE_BRUSH);
265 p = RotateAround(wxPoint2DDouble(m_position.m_x, m_position.m_y - m_height / 2.0 + 20), m_position, m_angle);
268 dc.SetPen(*wxTRANSPARENT_PEN);
269 dc.SetBrush(wxBrush(wxColour(elementColour)));
270 dc.DrawPolygon(3, triangPts);
272 dc.SetPen(wxPen(wxColour(elementColour), 2));
273 dc.DrawLines(2, arrowPts);
274 DrawDCGround(m_position + wxPoint2DDouble(0, 10.0), dc);
281 return m_rect.Contains(ptR);
291 double rotAngle = m_rotationAngle;
292 if (!clockwise) rotAngle = -m_rotationAngle;
295 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
298 UpdateSwitchesPosition();
310 wxString tipText = m_electricalData.name;
312 for (
unsigned int i = 0; i < m_electricalData.harmonicOrder.size(); ++i) {
314 wxString::Format(
"\nI%dh = %s %s (%s%s)", m_electricalData.harmonicOrder[i],
317 StringFromDouble(m_electricalData.injHarmAngle[i]),
static_cast<wxString
>(L
'\u00B0'));
326 harmCurrentForm.SetTitle(_(
"Harmonic Current Source"));
327 harmCurrentForm.CenterOnParent();
328 if (harmCurrentForm.ShowModal() == wxID_OK) {
337 double ib = systemPowerBase / (std::sqrt(3.00) * voltage);
338 for (
unsigned int i = 0; i < puData.harmonicOrder.size(); ++i) {
340 puData.injHarmCurrent[i] /= ib;
347rapidxml::xml_node<>* HarmCurrent::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
349 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"HarmCurrent");
350 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
352 SaveCADProperties(doc, elementNode);
354 auto electricalProp = XMLParser::AppendNode(doc, elementNode,
"ElectricalProperties");
355 auto isOnline = XMLParser::AppendNode(doc, electricalProp,
"IsOnline");
356 XMLParser::SetNodeValue(doc, isOnline, m_online);
357 auto name = XMLParser::AppendNode(doc, electricalProp,
"Name");
358 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
360 auto harmCurrentDataList = XMLParser::AppendNode(doc, electricalProp,
"HarmCurrentList");
361 for (
int i = 0; i < static_cast<int>(m_electricalData.harmonicOrder.size()); i++) {
362 auto harmCurrentData = XMLParser::AppendNode(doc, harmCurrentDataList,
"HarmCurrent");
363 XMLParser::SetNodeAttribute(doc, harmCurrentData,
"ID", i);
364 auto order = XMLParser::AppendNode(doc, harmCurrentData,
"Order");
365 XMLParser::SetNodeValue(doc, order, m_electricalData.harmonicOrder[i]);
366 auto injCurrent = XMLParser::AppendNode(doc, harmCurrentData,
"InjCurrent");
367 XMLParser::SetNodeValue(doc, injCurrent, m_electricalData.injHarmCurrent[i]);
368 XMLParser::SetNodeAttribute(doc, injCurrent,
"UnitID",
static_cast<int>(m_electricalData.injHarmCurrentUnit[i]));
369 auto injHarmAngle = XMLParser::AppendNode(doc, harmCurrentData,
"Angle");
370 XMLParser::SetNodeValue(doc, injHarmAngle, m_electricalData.injHarmAngle[i]);
376bool HarmCurrent::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Element*> parentList)
378 if (!OpenCADProperties(elementNode, parentList))
return false;
380 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
381 if (!electricalProp)
return false;
383 SetOnline(XMLParser::GetNodeValueInt(electricalProp,
"IsOnline"));
384 m_electricalData.name = electricalProp->first_node(
"Name")->value();
386 auto harmCurrentList = electricalProp->first_node(
"HarmCurrentList");
387 auto harmCurrent = harmCurrentList->first_node(
"HarmCurrent");
388 while (harmCurrent) {
389 m_electricalData.harmonicOrder.push_back(XMLParser::GetNodeValueInt(harmCurrent,
"Order"));
390 m_electricalData.injHarmCurrent.push_back(XMLParser::GetNodeValueDouble(harmCurrent,
"InjCurrent"));
391 m_electricalData.injHarmCurrentUnit.push_back(
392 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(harmCurrent,
"InjCurrent",
"UnitID")));
393 m_electricalData.injHarmAngle.push_back(XMLParser::GetNodeValueDouble(harmCurrent,
"Angle"));
394 harmCurrent = harmCurrent->next_sibling(
"HarmCurrent");
ElectricalUnit
Electrical units.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
virtual bool RotatedRectanglesIntersects(wxRect2DDouble rect1, wxRect2DDouble rect2, double angle1, double angle2) const
Check if two roteted rectangles intersect.
virtual void GeneralMenuItens(wxMenu &menu)
Insert general itens to context menu.
wxPoint2DDouble GetPosition() const
Get the element position.
double GetAngle() const
Get the element angle.
virtual void DrawDCTriangle(std::vector< wxPoint2DDouble > points, wxGraphicsContext *gc) const
Draw rectangle.
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
virtual void AddChild(Element *child)
Add a child to the child list.
static wxString StringFromDouble(double value, int minDecimal=1, int maxDecimals=13)
Convert a double value to string.
bool SetOnline(bool online=true)
Set if the element is online or offline.
virtual void DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
Draw a circle using device context.
Shunt Harmonic Corrent Source.
virtual wxString GetTipText() const
Get the tip text.
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
virtual Element * GetCopy()
Get a the element copy.
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
virtual void Rotate(bool clockwise=true)
Rotate the element.
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.
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
virtual bool AddParent(Element *parent, wxPoint2DDouble position)
Add a parent to the element. This method must be used on power elements that connect to a bus,...
virtual void DrawDCSwitches(wxGraphicsContext *gc) const
Draw switch.
virtual void UpdateSwitches()
Update the switch position.
virtual wxPoint2DDouble GetSwitchPoint(Element *parent, wxPoint2DDouble parentPoint, wxPoint2DDouble secondPoint) const
Get the correct switch position.
Abstract class for shunt power elements.