20#include "utils/DegreesAndRadians.h"
26 m_elementType = TYPE_BUS;
32Bus::Bus(wxPoint2DDouble position, wxString name)
34 m_elementType = TYPE_BUS;
39 m_electricalData.name = name;
44void Bus::DrawDC(
GUIColour* guiColour, wxPoint2DDouble translation,
double scale, wxGraphicsContext* gc)
const
46 wxPoint2DDouble gcPosition = m_position - wxPoint2DDouble(m_width / 2.0, m_height / 2.0);
47 wxGraphicsMatrix identityMatrix = gc->GetTransform();
50 gc->SetPen(*wxTRANSPARENT_PEN);
57 gc->SetTransform(identityMatrix);
60 gc->Translate(screenPt.m_x, screenPt.m_y);
61 gc->Rotate(wxDegToRad(m_angle));
62 gc->Translate(-screenPt.m_x, -screenPt.m_y);
64 gc->SetBrush(wxBrush(guiColour->selection));
66 wxPoint2DDouble pts[4] = {
WorldToScreen(translation, scale, -(m_width / 2.0), -(m_height / 2.0)) -
67 wxPoint2DDouble(m_borderSize, m_borderSize),
68 WorldToScreen(translation, scale, -(m_width / 2.0), (m_height / 2.0)) -
69 wxPoint2DDouble(m_borderSize, -m_borderSize),
70 WorldToScreen(translation, scale, (m_width / 2.0), (m_height / 2.0)) -
71 wxPoint2DDouble(-m_borderSize, -m_borderSize),
72 WorldToScreen(translation, scale, (m_width / 2.0), -(m_height / 2.0)) -
73 wxPoint2DDouble(-m_borderSize, m_borderSize) };
74 gc->DrawLines(4, pts);
79 gc->Translate(m_position.m_x, m_position.m_y);
80 gc->Rotate(wxDegToRad(m_angle));
81 gc->Translate(-m_position.m_x, -m_position.m_y);
84 if (!m_electricalData.isConnected)
85 gc->SetBrush(wxBrush(guiColour->disable));
88 else if (guiColour->useVoltageLevels)
89 gc->SetBrush(wxBrush(GetVoltageColour(guiColour)));
91 gc->SetBrush(wxBrush(guiColour->bus));
93 gc->DrawRectangle(gcPosition.m_x, gcPosition.m_y, m_width, m_height);
100 gc->SetTransform(identityMatrix);
102 wxPoint2DDouble screenPt =
WorldToScreen(translation, scale);
103 gc->Translate(screenPt.m_x, screenPt.m_y);
104 gc->Rotate(wxDegToRad(m_angle));
105 gc->Translate(-screenPt.m_x, -screenPt.m_y);
107 wxPoint2DDouble pbPosition[2] = {
WorldToScreen(translation, scale, m_width / 2.0) - wxPoint2DDouble(4, 4),
108 WorldToScreen(translation, scale, -m_width / 2.0) - wxPoint2DDouble(4, 4) };
116 if (m_electricalData.hasFault) {
118 gc->SetTransform(identityMatrix);
120 wxPoint2DDouble screenPt =
WorldToScreen(translation, scale);
121 gc->Translate(screenPt.m_x, screenPt.m_y);
122 gc->Rotate(wxDegToRad(m_angle));
123 gc->Translate(-screenPt.m_x, -screenPt.m_y);
125 wxPoint2DDouble fsPosition =
WorldToScreen(translation, scale, m_width / 2.0);
127 wxColour faultSymbolColour(255, 0, 0, 255);
131 gc->SetBrush(*wxRED_BRUSH);
132 gc->SetPen(*wxTRANSPARENT_PEN);
135 wxPoint2DDouble* points =
new wxPoint2DDouble[4];
136 points[0] = wxPoint2DDouble(fsPosition.m_x + 1 * scale, fsPosition.m_y + 3 * scale);
137 points[1] = wxPoint2DDouble(fsPosition.m_x + 1 * scale, fsPosition.m_y - 3 * scale);
138 points[2] = wxPoint2DDouble(fsPosition.m_x + 11 * scale, fsPosition.m_y - 1 * scale);
139 points[3] = wxPoint2DDouble(fsPosition.m_x + 11 * scale, fsPosition.m_y + 5 * scale);
141 gc->DrawLines(4, points);
143 points[0] = wxPoint2DDouble(fsPosition.m_x + 7 * scale, fsPosition.m_y - 5 * scale);
144 points[1] = wxPoint2DDouble(fsPosition.m_x + 21 * scale, fsPosition.m_y + 3 * scale);
145 points[2] = wxPoint2DDouble(fsPosition.m_x + 7 * scale, fsPosition.m_y + 1 * scale);
147 gc->DrawLines(3, points);
155 DrawStabilityEventGC(gc, translation, scale, guiColour,
true);
162 wxPoint2DDouble gcPosition = m_position;
164 dc.SetPen(*wxTRANSPARENT_PEN);
168 dc.SetBrush(wxBrush(guiColour->selection));
170 wxPoint2DDouble pts[4] = {
WorldToScreen(translation, scale, -(m_width / 2.0), -(m_height / 2.0)) -
171 wxPoint2DDouble(m_borderSize, m_borderSize),
172 WorldToScreen(translation, scale, -(m_width / 2.0), (m_height / 2.0)) -
173 wxPoint2DDouble(m_borderSize, -m_borderSize),
174 WorldToScreen(translation, scale, (m_width / 2.0), (m_height / 2.0)) -
175 wxPoint2DDouble(-m_borderSize, -m_borderSize),
176 WorldToScreen(translation, scale, (m_width / 2.0), -(m_height / 2.0)) -
177 wxPoint2DDouble(-m_borderSize, m_borderSize) };
179 DrawDCRectangle(gcPosition, m_width + 2 * m_borderSize, m_height + 2 * m_borderSize, m_angle, dc);
183 if (!m_electricalData.isConnected)
184 dc.SetBrush(wxBrush(guiColour->disable));
185 else if (m_dynEvent || m_electricalData.hasFault)
186 dc.SetBrush(wxBrush(guiColour->eventElement));
188 dc.SetBrush(wxBrush(GetVoltageColour(guiColour)));
194 if (m_electricalData.hasFault) {
196 wxPoint2DDouble center = m_position;
197 wxPoint2DDouble fsPosition = center + wxPoint2DDouble(m_width / 2.0, 0.0);
199 wxColour faultSymbolColour(255, 0, 0, 255);
201 double localScale = 1.5;
203 dc.SetBrush(*wxRED_BRUSH);
204 dc.SetPen(*wxTRANSPARENT_PEN);
212 p = wxPoint2DDouble(fsPosition.m_x + 1 * localScale, fsPosition.m_y + 3 * localScale);
213 points[0] = RotateAround(p, center, m_angle);
214 p = wxPoint2DDouble(fsPosition.m_x + 1 * localScale, fsPosition.m_y - 3 * localScale);
215 points[1] = RotateAround(p, center, m_angle);
216 p = wxPoint2DDouble(fsPosition.m_x + 11 * localScale, fsPosition.m_y - 1 * localScale);
217 points[2] = RotateAround(p, center, m_angle);
218 p = wxPoint2DDouble(fsPosition.m_x + 11 * localScale, fsPosition.m_y + 5 * localScale);
219 points[3] = RotateAround(p, center, m_angle);
221 dc.DrawPolygon(4, points);
223 p = wxPoint2DDouble(fsPosition.m_x + 7 * localScale, fsPosition.m_y - 5 * localScale);
224 points[0] = RotateAround(p, center, m_angle);
225 p = wxPoint2DDouble(fsPosition.m_x + 21 * localScale, fsPosition.m_y + 3 * localScale);
226 points[1] = RotateAround(p, center, m_angle);
227 p = wxPoint2DDouble(fsPosition.m_x + 7 * localScale, fsPosition.m_y + 1 * localScale);
228 points[2] = RotateAround(p, center, m_angle);
230 dc.DrawPolygon(3, points);
237 return m_rect.Contains(ptR);
242 if (m_angle == 0.0 || m_angle == 180.0)
return m_rect.Intersects(rect);
253 wxPoint2DDouble center(m_position.m_x + m_width / 2.0, m_position.m_y);
254 wxRect2DDouble rectRight(center.m_x - 5.0, center.m_y - 5.0, 10.0, 10.0);
256 center = wxPoint2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y);
257 wxRect2DDouble rectLeft(center.m_x - 5.0, center.m_y - 5.0, 10.0, 10.0);
259 if (rectRight.Contains(ptR)) {
263 if (rectLeft.Contains(ptR)) {
273 double angle = m_angle;
274 while (angle >= 157.5) angle -= 180.0;
276 if (angle >= -22.5 && angle < 22.5)
277 return wxCursor(wxCURSOR_SIZEWE);
278 else if (angle >= 22.5 && angle < 67.5)
279 return wxCursor(wxCURSOR_SIZENWSE);
280 else if (angle >= 67.5 && angle < 112.5)
281 return wxCursor(wxCURSOR_SIZENS);
282 else if (angle >= 112.5 && angle < 157.5)
283 return wxCursor(wxCURSOR_SIZENESW);
285 return wxCursor(wxCURSOR_ARROW);
296 dx = ptR.m_x - m_position.m_x - m_width / 2.0;
298 dx = m_position.m_x - m_width / 2.0 - ptR.m_x;
300 if (m_width + dx < 20.0)
return;
303 m_position.m_x += (dx / 2.0) * std::cos(wxDegToRad(m_angle));
304 m_position.m_y += (dx / 2.0) * std::sin(wxDegToRad(m_angle));
307 m_position.m_x -= (dx / 2.0) * std::cos(wxDegToRad(m_angle));
308 m_position.m_y -= (dx / 2.0) * std::sin(wxDegToRad(m_angle));
317 double rotAngle = m_rotationAngle;
318 if (!clockwise) rotAngle = -m_rotationAngle;
321 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
324void Bus::AlignToGrid(
double gridSize)
326 if (gridSize <= 0.0) gridSize = 20.0;
327 wxPoint2DDouble newPos(std::round(m_position.m_x / gridSize) * gridSize,
328 std::round(m_position.m_y / gridSize) * gridSize);
329 m_width = std::round(m_width / gridSize) * gridSize;
330 if (m_width < gridSize) m_width = gridSize;
338 wxMenu* textMenu =
new wxMenu();
340 textMenu->Append(ID_TXT_NAME, _(
"Name"));
341 textMenu->Append(ID_TXT_VOLTAGE, _(
"Voltage"));
342 textMenu->Append(ID_TXT_ANGLE, _(
"Angle"));
343 textMenu->Append(ID_TXT_FAULTCURRENT, _(
"Fault current"));
344 textMenu->Append(ID_TXT_FAULTVOLTAGE, _(
"Fault voltage"));
345 textMenu->Append(ID_TXT_SCC, _(
"Short-circuit power"));
346 textMenu->Append(ID_TXT_THD, _(
"Voltage THD"));
347 textMenu->SetClientData(menu.GetClientData());
350 menu.AppendSubMenu(textMenu, _(
"Add text"));
358 busForm.CentreOnParent();
359 if (busForm.ShowModal() == wxID_OK) {
372wxColour Bus::GetVoltageColour(
GUIColour* guiColour)
const
374 double v_kV = m_electricalData.nominalVoltage;
375 if (m_electricalData.nominalVoltageUnit == ElectricalUnit::UNIT_V) {
379 const std::vector<VoltageLevelColour>* levels =
nullptr;
380 if (guiColour && !guiColour->voltageLevels.empty()) {
381 levels = &guiColour->voltageLevels;
384 if (levels && !levels->empty()) {
386 double minDiff = 1e9;
388 for (
size_t i = 0; i < levels->size(); ++i) {
389 double diff = std::abs(v_kV - (*levels)[i].voltage);
390 if (diff < minDiff) {
392 bestIdx =
static_cast<int>(i);
397 double tol = std::max((*levels)[bestIdx].voltage * 0.15, 0.5);
398 if (minDiff <= tol) {
399 return (*levels)[bestIdx].colour;
402 for (
size_t i = 0; i < levels->size(); ++i) {
403 if (v_kV >= (*levels)[i].voltage * 0.9) {
404 return (*levels)[i].colour;
407 return levels->back().colour;
412 return wxColour(0, 90, 220);
413 }
else if (v_kV >= 300.0) {
414 return wxColour(160, 82, 45);
415 }
else if (v_kV >= 200.0) {
416 return wxColour(220, 35, 35);
417 }
else if (v_kV >= 100.0) {
418 return wxColour(0, 155, 65);
419 }
else if (v_kV >= 50.0) {
420 return wxColour(145, 40, 205);
421 }
else if (v_kV >= 20.0) {
422 return wxColour(215, 35, 135);
423 }
else if (v_kV >= 10.0) {
424 return wxColour(0, 165, 195);
425 }
else if (v_kV >= 1.0) {
426 return wxColour(205, 150, 15);
428 return wxColour(120, 125, 135);
434 wxString tipText = m_electricalData.name;
435 tipText += wxString::Format(
" (%d)", m_electricalData.number + 1);
438 (m_electricalData.nominalVoltageUnit == ElectricalUnit::UNIT_V
442 tipText += _(
"\nV = ") + wxString::FromDouble(std::abs(m_electricalData.voltage), 5) + _(
" p.u.");
444 tipText += wxString(L
'\u03B8') +
" = " + wxString::FromDouble(wxRadToDeg(std::arg(m_electricalData.voltage)), 5)
445 + wxString(L
'\u00B0');
447 tipText += _(
"\n\nFault info:");
448 tipText += _(
"\nVa = ") + wxString::FromDouble(std::abs(m_electricalData.faultVoltage[0]), 5) + _(
" p.u.");
449 tipText += _(
"\nVb = ") + wxString::FromDouble(std::abs(m_electricalData.faultVoltage[1]), 5) + _(
" p.u.");
450 tipText += _(
"\nVc = ") + wxString::FromDouble(std::abs(m_electricalData.faultVoltage[2]), 5) + _(
" p.u.");
451 if (m_electricalData.hasFault) {
452 tipText += _(
"\nIa = ") + wxString::FromDouble(std::abs(m_electricalData.faultCurrent[0]), 5) + _(
" p.u.");
453 tipText += _(
"\nIb = ") + wxString::FromDouble(std::abs(m_electricalData.faultCurrent[1]), 5) + _(
" p.u.");
454 tipText += _(
"\nIc = ") + wxString::FromDouble(std::abs(m_electricalData.faultCurrent[2]), 5) + _(
" p.u.");
457 tipText += _(
"\n\nSsc = ") + wxString::FromDouble(std::abs(m_electricalData.scPower), 5) + _(
" p.u.");
459 wxString harmonicsInfo = _(
"\n\nHarmonics info:");
460 bool hasHarmonics =
false;
461 harmonicsInfo += _(
"\nTHD = ") + wxString::FromDouble(std::abs(m_electricalData.thd), 5) + wxT(
"%");
463 for (
auto& hVoltage : m_electricalData.harmonicVoltage) {
465 wxString hVoltageStr;
466 hVoltageStr.Printf(_(
"\nVh(%d) = %.5e%s%.2f%s p.u."), m_electricalData.harmonicOrder[i], std::abs(hVoltage), wxString(L
'\u2220'), wxRadToDeg(std::arg(hVoltage)), wxString(L
'\u00B0'));
467 harmonicsInfo += hVoltageStr;
470 if (hasHarmonics) tipText += harmonicsInfo;
478 if (!m_electricalData.plotBus)
return false;
479 plotData.SetName(m_electricalData.name);
480 plotData.SetCurveType(ElementPlotData::CurveType::CT_BUS);
482 std::vector<double> absVoltage, argVoltage;
483 for (
unsigned int i = 0; i < m_electricalData.stabVoltageVector.size(); ++i) {
484 absVoltage.push_back(std::abs(m_electricalData.stabVoltageVector[i]));
485 argVoltage.push_back(wxRadToDeg(std::arg(m_electricalData.stabVoltageVector[i])));
487 plotData.AddData(absVoltage, _(
"Voltage"));
488 plotData.AddData(argVoltage, _(
"Angle"));
489 plotData.AddData(m_electricalData.stabFreqVector, _(
"Frequency"));
493 if (!m_electricalData.plotPQData)
return false;
494 plotData.SetName(m_electricalData.name);
495 plotData.SetCurveType(ElementPlotData::CurveType::CT_BUS);
496 plotData.AddData(m_electricalData.absImpedanceVector, _(
"Impedance"));
497 const auto& z = m_electricalData.complexImpedanceVector;
498 std::vector<double> r(z.size());
499 std::vector<double> x(z.size());
500 for (std::size_t i = 0; i < z.size(); ++i) {
504 plotData.AddData(r, _(
"Resistance"));
505 plotData.AddData(x, _(
"Reactance"));
511rapidxml::xml_node<>* Bus::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
513 m_electricalData.number = m_elementID;
515 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"Bus");
516 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
518 Element::SaveCADProperties(doc, elementNode);
520 auto electricalProp = XMLParser::AppendNode(doc, elementNode,
"ElectricalProperties");
521 auto name = XMLParser::AppendNode(doc, electricalProp,
"Name");
522 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
523 auto nominalVoltage = XMLParser::AppendNode(doc, electricalProp,
"NominalVoltage");
524 XMLParser::SetNodeValue(doc, nominalVoltage, m_electricalData.nominalVoltage);
525 XMLParser::SetNodeAttribute(doc, nominalVoltage,
"UnitID",
static_cast<int>(m_electricalData.nominalVoltageUnit));
526 auto isVoltageControlled = XMLParser::AppendNode(doc, electricalProp,
"IsVoltageControlled");
527 XMLParser::SetNodeValue(doc, isVoltageControlled, m_electricalData.isVoltageControlled);
528 auto controlledVoltage = XMLParser::AppendNode(doc, electricalProp,
"ControlledVoltage");
529 XMLParser::SetNodeValue(doc, controlledVoltage, m_electricalData.controlledVoltage);
530 XMLParser::SetNodeAttribute(doc, controlledVoltage,
"Choice", m_electricalData.controlledVoltageUnitChoice);
531 auto slackBus = XMLParser::AppendNode(doc, electricalProp,
"SlackBus");
532 XMLParser::SetNodeValue(doc, slackBus, m_electricalData.slackBus);
534 auto fault = XMLParser::AppendNode(doc, electricalProp,
"Fault");
535 auto hasFault = XMLParser::AppendNode(doc, fault,
"HasFault");
536 XMLParser::SetNodeValue(doc, hasFault, m_electricalData.hasFault);
537 auto faultType = XMLParser::AppendNode(doc, fault,
"Type");
538 XMLParser::SetNodeValue(doc, faultType,
static_cast<int>(m_electricalData.faultType));
539 auto faultLocation = XMLParser::AppendNode(doc, fault,
"Location");
540 XMLParser::SetNodeValue(doc, faultLocation,
static_cast<int>(m_electricalData.faultLocation));
541 auto faultResistance = XMLParser::AppendNode(doc, fault,
"Resistance");
542 XMLParser::SetNodeValue(doc, faultResistance, m_electricalData.faultResistance);
543 auto faultReactance = XMLParser::AppendNode(doc, fault,
"Reactance");
544 XMLParser::SetNodeValue(doc, faultReactance, m_electricalData.faultReactance);
546 auto stability = XMLParser::AppendNode(doc, electricalProp,
"Stability");
547 auto plotBus = XMLParser::AppendNode(doc, stability,
"Plot");
548 XMLParser::SetNodeValue(doc, plotBus, m_electricalData.plotBus);
549 auto stabHasFault = XMLParser::AppendNode(doc, stability,
"HasFault");
550 XMLParser::SetNodeValue(doc, stabHasFault, m_electricalData.stabHasFault);
551 auto stabFaultTime = XMLParser::AppendNode(doc, stability,
"FaultTime");
552 XMLParser::SetNodeValue(doc, stabFaultTime, m_electricalData.stabFaultTime);
553 auto stabFaultLength = XMLParser::AppendNode(doc, stability,
"FaultLength");
554 XMLParser::SetNodeValue(doc, stabFaultLength, m_electricalData.stabFaultLength);
555 auto stabFaultResistance = XMLParser::AppendNode(doc, stability,
"FaultResistance");
556 XMLParser::SetNodeValue(doc, stabFaultResistance, m_electricalData.stabFaultResistance);
557 auto stabFaultReactance = XMLParser::AppendNode(doc, stability,
"FaultReactance");
558 XMLParser::SetNodeValue(doc, stabFaultReactance, m_electricalData.stabFaultReactance);
560 auto powerQuality = XMLParser::AppendNode(doc, electricalProp,
"PowerQuality");
561 auto plotPQData = XMLParser::AppendNode(doc, powerQuality,
"Plot");
562 XMLParser::SetNodeValue(doc, plotPQData, m_electricalData.plotPQData);
567bool Bus::OpenElement(rapidxml::xml_node<>* elementNode)
569 if (!Element::OpenCADProperties(elementNode))
return false;
571 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
572 if (!electricalProp)
return false;
574 m_electricalData.name = electricalProp->first_node(
"Name")->value();
575 m_electricalData.nominalVoltage = XMLParser::GetNodeValueDouble(electricalProp,
"NominalVoltage");
576 m_electricalData.nominalVoltageUnit =
577 (ElectricalUnit)XMLParser::GetAttributeValueInt(electricalProp,
"NominalVoltage",
"UnitID");
578 m_electricalData.isVoltageControlled = XMLParser::GetNodeValueInt(electricalProp,
"IsVoltageControlled");
579 m_electricalData.controlledVoltage = XMLParser::GetNodeValueDouble(electricalProp,
"ControlledVoltage");
580 m_electricalData.controlledVoltageUnitChoice =
581 XMLParser::GetAttributeValueInt(electricalProp,
"ControlledVoltage",
"Choice");
582 m_electricalData.slackBus = XMLParser::GetNodeValueInt(electricalProp,
"SlackBus");
583 auto fault = electricalProp->first_node(
"Fault");
584 m_electricalData.hasFault = XMLParser::GetNodeValueInt(fault,
"HasFault");
585 m_electricalData.faultType = (
FaultData)XMLParser::GetNodeValueInt(fault,
"Type");
586 m_electricalData.faultLocation = (
FaultData)XMLParser::GetNodeValueInt(fault,
"Location");
587 m_electricalData.faultResistance = XMLParser::GetNodeValueDouble(fault,
"Resistance");
588 m_electricalData.faultReactance = XMLParser::GetNodeValueDouble(fault,
"Reactance");
589 auto stability = electricalProp->first_node(
"Stability");
590 m_electricalData.plotBus = XMLParser::GetNodeValueInt(stability,
"Plot");
591 m_electricalData.stabHasFault = XMLParser::GetNodeValueInt(stability,
"HasFault");
592 m_electricalData.stabFaultTime = XMLParser::GetNodeValueDouble(stability,
"FaultTime");
593 m_electricalData.stabFaultLength = XMLParser::GetNodeValueDouble(stability,
"FaultLength");
594 m_electricalData.stabFaultResistance = XMLParser::GetNodeValueDouble(stability,
"FaultResistance");
595 m_electricalData.stabFaultReactance = XMLParser::GetNodeValueDouble(stability,
"FaultReactance");
597 auto powerQuality = electricalProp->first_node(
"PowerQuality");
598 if (powerQuality) m_electricalData.plotPQData = XMLParser::GetNodeValueInt(powerQuality,
"Plot");
FaultData
Information about fault (type and location).
Node for power elements. All others power elements are connected through this.
virtual bool PickboxContains(wxPoint2DDouble position)
Check if a pickbox contains a point. If contains the attributes related to pickbox movement will be c...
virtual wxString GetTipText() const
Get the tip text.
virtual bool GetPlotData(ElementPlotData &plotData, PlotStudy study=PlotStudy::STABILITY)
Fill the plot data.
virtual void DrawDC(GUIColour *guiColour, wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
virtual Element * GetCopy()
Get a the element copy.
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
Bus()
Default constructor.
virtual wxCursor GetBestPickboxCursor() const
Get the best cursor to shown to the user when the mouse is above a pickbox.
virtual void Rotate(bool clockwise=true)
Rotate the element.
virtual bool Contains(wxPoint2DDouble position) const
Checks if the element contains a position.
virtual void MovePickbox(wxPoint2DDouble position)
Move the pickbox.
virtual bool ShowForm(wxWindow *parent, Element *element, wxWindow *workspace=nullptr)
Show element data form.
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
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.
virtual void DrawDCRectangle(wxPoint2DDouble position, double width, double height, double angle, wxDC &dc) const
Draw a circle.
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
virtual void DrawDCPickbox(wxPoint2DDouble position, wxGraphicsContext *gc) const
Draw a point.
virtual wxPoint2DDouble WorldToScreen(wxPoint2DDouble translation, double scale, double offsetX=0.0, double offsetY=0.0) const
Convert the element position to screen position.
static wxString StringFromDouble(double value, int minDecimal=1, int maxDecimals=13)
Convert a double value to string.
void SetInserted(bool inserted=true)
Set if the element is properly inserted in the workspace.
Abstract class of power elements.
virtual void SetDynamicEvent(bool dynEvent=true)
Set if the power element have dynamic event.