19#include "../../forms/ReactiveShuntElementForm.h"
21Capacitor::Capacitor() :
Shunt() {
22 m_elementType = TYPE_CAPACITOR;
25Capacitor::Capacitor(wxString name) :
Shunt() {
26 m_elementType = TYPE_CAPACITOR;
27 m_electricalData.name = name;
30Capacitor::~Capacitor() {}
35 m_parentList.push_back(parent);
37 wxPoint2DDouble parentPt =
42 m_position = parentPt + wxPoint2DDouble(0.0, 100.0);
45 m_rect = wxRect2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0, m_width, m_height);
47 m_pointList.push_back(parentPt);
48 m_pointList.push_back(
GetSwitchPoint(parent, parentPt, m_position));
49 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -m_height / 2.0 - 10.0));
50 m_pointList.push_back(m_position + wxPoint2DDouble(0.0, -m_height / 2.0));
54 wxRect2DDouble genRect(0, 0, 0, 0);
55 m_switchRect.push_back(genRect);
126 wxColour elementColour;
129 elementColour = m_dynamicEventColour;
131 elementColour = m_onlineElementColour;
134 elementColour = m_offlineElementColour;
137 std::vector<wxPoint2DDouble> capPts;
138 capPts.push_back(wxPoint2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0));
139 capPts.push_back(wxPoint2DDouble(m_position.m_x + m_width / 2.0, m_position.m_y - m_height / 2.0));
140 capPts.push_back(wxPoint2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0 + 10.0));
141 capPts.push_back(wxPoint2DDouble(m_position.m_x + m_width / 2.0, m_position.m_y - m_height / 2.0 + 10.0));
144 gc->SetPen(wxPen(wxColour(m_selectionColour), 2 + m_borderSize * 2.0));
145 gc->SetBrush(*wxTRANSPARENT_BRUSH);
147 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
152 gc->Translate(m_position.m_x, m_position.m_y);
153 gc->Rotate(wxDegToRad(m_angle));
154 gc->Translate(-m_position.m_x, -m_position.m_y);
156 gc->StrokeLines(2, &capPts[0]);
157 gc->StrokeLines(2, &capPts[2]);
159 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), gc);
164 gc->SetPen(*wxTRANSPARENT_PEN);
165 gc->SetBrush(wxBrush(wxColour(m_selectionColour)));
166 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, 10, gc);
170 gc->SetPen(*wxTRANSPARENT_PEN);
171 gc->SetBrush(wxBrush(wxColour(elementColour)));
174 gc->SetPen(wxPen(wxColour(elementColour), 2));
175 gc->SetBrush(*wxTRANSPARENT_BRUSH);
176 gc->StrokeLines(m_pointList.size(), &m_pointList[0]);
183 gc->Translate(m_position.m_x, m_position.m_y);
184 gc->Rotate(wxDegToRad(m_angle));
185 gc->Translate(-m_position.m_x, -m_position.m_y);
187 gc->SetPen(wxPen(wxColour(elementColour), 2));
188 gc->SetBrush(*wxTRANSPARENT_BRUSH);
189 gc->StrokeLines(2, &capPts[0]);
190 gc->StrokeLines(2, &capPts[2]);
192 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), gc);
200 wxColour elementColour;
203 elementColour = m_dynamicEventColour;
205 elementColour = m_onlineElementColour;
208 elementColour = m_offlineElementColour;
213 p = wxPoint2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0);
214 capPts[0] = RotateAround(p, m_position, m_angle);
216 p = wxPoint2DDouble(m_position.m_x + m_width / 2.0, m_position.m_y - m_height / 2.0);
217 capPts[1] = RotateAround(p, m_position, m_angle);
219 p = wxPoint2DDouble(m_position.m_x - m_width / 2.0, m_position.m_y - m_height / 2.0 + 10.0);
220 capPts[2] = RotateAround(p, m_position, m_angle);
221 p = wxPoint2DDouble(m_position.m_x + m_width / 2.0, m_position.m_y - m_height / 2.0 + 10.0);
222 capPts[3] = RotateAround(p, m_position, m_angle);
224 std::vector<wxPoint> pointListInt;
225 for (
auto& pt : m_pointList) {
226 pointListInt.emplace_back(
static_cast<int>(pt.m_x),
static_cast<int>(pt.m_y));
230 dc.SetPen(wxPen(wxColour(m_selectionColour), 2 + m_borderSize * 2.0));
231 dc.SetBrush(*wxTRANSPARENT_BRUSH);
233 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
236 dc.DrawLines(2, &capPts[0]);
237 dc.DrawLines(2, &capPts[2]);
239 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), dc);
242 dc.SetPen(*wxTRANSPARENT_PEN);
243 dc.SetBrush(wxBrush(wxColour(m_selectionColour)));
244 DrawDCCircle(m_pointList[0], 5.0 + m_borderSize / scale, dc);
248 dc.SetPen(*wxTRANSPARENT_PEN);
249 dc.SetBrush(wxBrush(wxColour(elementColour)));
252 dc.SetPen(wxPen(wxColour(elementColour), 2));
253 dc.SetBrush(*wxTRANSPARENT_BRUSH);
254 dc.DrawLines(pointListInt.size(), &pointListInt[0]);
258 dc.SetPen(wxPen(wxColour(elementColour), 2));
259 dc.SetBrush(*wxTRANSPARENT_BRUSH);
260 dc.DrawLines(2, &capPts[0]);
261 dc.DrawLines(2, &capPts[2]);
263 DrawDCGround(m_position + wxPoint2DDouble(0, -m_height / 2.0 + 10.0), dc);
269 double rotAngle = m_rotationAngle;
270 if (!clockwise) rotAngle = -m_rotationAngle;
273 if (m_angle >= 360 || m_angle <= -360) m_angle = 0.0;
276 UpdateSwitchesPosition();
283 wxMenu* textMenu =
new wxMenu();
285 textMenu->Append(ID_TXT_NAME, _(
"Name"));
286 textMenu->Append(ID_TXT_REACTIVE_POWER, _(
"Reactive power"));
287 textMenu->SetClientData(menu.GetClientData());
288 menu.AppendSubMenu(textMenu, _(
"Add text"));
297 return m_rect.Contains(ptR);
308 capacitorForm.SetTitle(_(
"Capacitor"));
309 capacitorForm.CenterOnParent();
310 if (capacitorForm.ShowModal() == wxID_OK) {
319 switch (data.reactivePowerUnit) {
321 data.reactivePower = data.reactivePower / systemPowerBase;
325 data.reactivePower = (data.reactivePower * 1e3) / systemPowerBase;
329 data.reactivePower = (data.reactivePower * 1e6) / systemPowerBase;
348 wxString tipText = m_electricalData.name;
351 double reactivePower = m_electricalData.reactivePower;
355 std::complex<double> v =
static_cast<Bus*
>(m_parentList[0])->GetElectricalData().voltage;
356 reactivePower *= std::pow(std::abs(v), 2);
359 tipText += _(
"\nQ = ") + wxString::FromDouble(reactivePower, 5);
360 switch (m_electricalData.reactivePowerUnit) {
362 tipText += _(
" p.u.");
365 tipText += _(
" var");
368 tipText += _(
" kvar");
371 tipText += _(
" Mvar");
380rapidxml::xml_node<>* Capacitor::SaveElement(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementListNode)
382 auto elementNode = XMLParser::AppendNode(doc, elementListNode,
"Capacitor");
383 XMLParser::SetNodeAttribute(doc, elementNode,
"ID", m_elementID);
385 SaveCADProperties(doc, elementNode);
387 auto electricalProp = XMLParser::AppendNode(doc, elementNode,
"ElectricalProperties");
388 auto isOnline = XMLParser::AppendNode(doc, electricalProp,
"IsOnline");
389 XMLParser::SetNodeValue(doc, isOnline, m_online);
390 auto name = XMLParser::AppendNode(doc, electricalProp,
"Name");
391 XMLParser::SetNodeValue(doc, name, m_electricalData.name);
392 auto reactivePower = XMLParser::AppendNode(doc, electricalProp,
"ReactivePower");
393 XMLParser::SetNodeValue(doc, reactivePower, m_electricalData.reactivePower);
394 XMLParser::SetNodeAttribute(doc, reactivePower,
"UnitID",
static_cast<int>(m_electricalData.reactivePowerUnit));
396 SaveSwitchingData(doc, electricalProp);
401bool Capacitor::OpenElement(rapidxml::xml_node<>* elementNode, std::vector<Element*> parentList)
403 if (!OpenCADProperties(elementNode, parentList))
return false;
405 auto electricalProp = elementNode->first_node(
"ElectricalProperties");
406 if (!electricalProp)
return false;
408 SetOnline(XMLParser::GetNodeValueInt(electricalProp,
"IsOnline"));
409 m_electricalData.name = electricalProp->first_node(
"Name")->value();
410 m_electricalData.reactivePower = XMLParser::GetNodeValueDouble(electricalProp,
"ReactivePower");
411 m_electricalData.reactivePowerUnit =
412 static_cast<ElectricalUnit>(XMLParser::GetAttributeValueInt(electricalProp,
"ReactivePower",
"UnitID"));
414 if (!OpenSwitchingData(electricalProp))
return false;
ElectricalUnit
Electrical units.
Node for power elements. All others power elements are connected through this.
Shunt capactior power element.
virtual wxString GetTipText() const
Get the tip text.
virtual bool GetContextMenu(wxMenu &menu)
Get the element contex menu.
virtual void Rotate(bool clockwise=true)
Rotate the element.
virtual Element * GetCopy()
Get a the element copy.
virtual bool ShowForm(wxWindow *parent, Element *element)
Show element data form.
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
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 DrawDC(wxPoint2DDouble translation, double scale, wxGraphicsContext *gc) const
Draw the element using GDI+.
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 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.
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.
virtual void SetDynamicEvent(bool dynEvent=true)
Set if the power element have dynamic event.
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.
std::vector< double > swTime