Power System Platform  2026w10a-beta
Loading...
Searching...
No Matches
Branch.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 "Branch.h"
19
20Branch::Branch() : PowerElement() {}
21Branch::~Branch() {}
22bool Branch::NodeContains(wxPoint2DDouble position)
23{
24 wxRect2DDouble nodeRect1(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
25 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
26 wxRect2DDouble nodeRect2(m_pointList[m_pointList.size() - 1].m_x - 5.0 - m_borderSize,
27 m_pointList[m_pointList.size() - 1].m_y - 5.0 - m_borderSize, 10 + 2.0 * m_borderSize,
28 10 + 2.0 * m_borderSize);
29
30 if(nodeRect1.Contains(position)) {
31 m_activeNodeID = 1;
32 return true;
33 }
34 if(nodeRect2.Contains(position)) {
35 m_activeNodeID = 2;
36 return true;
37 }
38
39 m_activeNodeID = 0;
40 return false;
41}
42
44{
45 if(m_activeNodeID == 1 && parent == m_parentList[0]) return false;
46 if(m_activeNodeID == 2 && parent == m_parentList[1]) return false;
47
48 if(parent && m_activeNodeID != 0) {
49 wxRect2DDouble nodeRect(0, 0, 0, 0);
50 if(m_activeNodeID == 1) {
51 nodeRect = wxRect2DDouble(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
52 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
53 }
54 if(m_activeNodeID == 2) {
55 nodeRect = wxRect2DDouble(m_pointList[m_pointList.size() - 1].m_x - 5.0 - m_borderSize,
56 m_pointList[m_pointList.size() - 1].m_y - 5.0 - m_borderSize,
57 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
58 }
59
60 if(parent->Intersects(nodeRect)) {
61 if(m_activeNodeID == 1) {
62 // Check if the user is trying to connect the same bus.
63 if(m_parentList[1] == parent) {
64 m_activeNodeID = 0;
65 return false;
66 }
67
68 m_parentList[0] = parent;
69
70 // Centralize the node on bus.
71 wxPoint2DDouble parentPt = parent->RotateAtPosition(
72 m_pointList[0], -parent->GetAngle()); // Rotate click to horizontal position.
73 parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus.
74 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
75 m_pointList[0] = parentPt;
76
77 UpdateSwitchesPosition();
78 return true;
79 }
80 if(m_activeNodeID == 2) {
81 if(m_parentList[0] == parent) {
82 m_activeNodeID = 0;
83 return false;
84 }
85
86 m_parentList[1] = parent;
87
88 wxPoint2DDouble parentPt =
89 parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], -parent->GetAngle());
90 parentPt.m_y = parent->GetPosition().m_y;
91 parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle());
92 m_pointList[m_pointList.size() - 1] = parentPt;
93
94 UpdateSwitchesPosition();
95 return true;
96 }
97 } else {
98 if(m_activeNodeID == 1) m_parentList[0] = nullptr;
99 if(m_activeNodeID == 2) m_parentList[1] = nullptr;
100 }
101 }
102 return false;
103}
104
106{
107 for(unsigned int i = 0; i < m_parentList.size(); i++) {
108 if(parent == m_parentList[i]) {
109 m_parentList[i] = nullptr;
110 m_online = false;
111 UpdateSwitchesPosition();
112 }
113 }
114}
115
117{
118 if(m_parentList[0]) {
119 wxRect2DDouble nodeRect(m_pointList[0].m_x - 5.0 - m_borderSize, m_pointList[0].m_y - 5.0 - m_borderSize,
120 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
121
122 if(!m_parentList[0]->Intersects(nodeRect)) {
123 m_parentList[0]->RemoveChild(this);
124 m_parentList[0] = nullptr;
125 m_online = false;
126 UpdateSwitchesPosition();
127 }
128 }
129 if(m_parentList[1]) {
130 wxRect2DDouble nodeRect = wxRect2DDouble(m_pointList[m_pointList.size() - 1].m_x - 5.0 - m_borderSize,
131 m_pointList[m_pointList.size() - 1].m_y - 5.0 - m_borderSize,
132 10 + 2.0 * m_borderSize, 10 + 2.0 * m_borderSize);
133
134 if(!m_parentList[1]->Intersects(nodeRect)) {
135 m_parentList[1]->RemoveChild(this);
136 m_parentList[1] = nullptr;
137 m_online = false;
138 UpdateSwitchesPosition();
139 }
140 }
141}
142
143void Branch::RotateNode(Element* parent, bool clockwise)
144{
145 double rotAngle = m_rotationAngle;
146 if(!clockwise) rotAngle = -m_rotationAngle;
147
148 if(parent == m_parentList[0]) {
149 m_pointList[0] = parent->RotateAtPosition(m_pointList[0], rotAngle);
150 } else if(parent == m_parentList[1]) {
151 m_pointList[m_pointList.size() - 1] = parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], rotAngle);
152 }
153 UpdateSwitchesPosition();
154}
155
156void Branch::UpdateSwitchesPosition()
157{
158 if (m_parentList.size() >= 1) {
159 if (m_parentList[0]) {
160 m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], m_pointList[2]);
161 }
162 else {
163 m_pointList[1] = m_pointList[0];
164 }
165 }
166
167 if (m_parentList.size() >= 2) {
168 if (m_parentList[1]) {
169 m_pointList[m_pointList.size() - 2] =
170 GetSwitchPoint(m_parentList[1], m_pointList[m_pointList.size() - 1], m_pointList[m_pointList.size() - 3]);
171 }
172 else {
173 m_pointList[m_pointList.size() - 2] = m_pointList[m_pointList.size() - 1];
174 }
175 }
177}
178
180{
181 wxPoint2DDouble swCenter = wxPoint2DDouble((m_pointList[0].m_x + m_pointList[1].m_x) / 2.0,
182 (m_pointList[0].m_y + m_pointList[1].m_y) / 2.0);
183 m_switchRect[0] = wxRect2DDouble(swCenter.m_x - m_switchSize / 2.0, swCenter.m_y - m_switchSize / 2.0, m_switchSize,
184 m_switchSize);
185
186 if(m_switchRect.size() > 1) {
187 swCenter =
188 wxPoint2DDouble((m_pointList[m_pointList.size() - 1].m_x + m_pointList[m_pointList.size() - 2].m_x) / 2.0,
189 (m_pointList[m_pointList.size() - 1].m_y + m_pointList[m_pointList.size() - 2].m_y) / 2.0);
190 m_switchRect[1] = wxRect2DDouble(swCenter.m_x - m_switchSize / 2.0, swCenter.m_y - m_switchSize / 2.0,
191 m_switchSize, m_switchSize);
192 }
193}
virtual void UpdateSwitches()
Update the switch position.
Definition Branch.cpp:179
virtual void RotateNode(Element *parent, bool clockwise=true)
Rotate a node.
Definition Branch.cpp:143
virtual void UpdateNodes()
Update the nodes according to the parents. If a parent is removed, use this method.
Definition Branch.cpp:116
virtual bool NodeContains(wxPoint2DDouble position)
Check if a node contains a point. If contains, set the attributes related to node movement.
Definition Branch.cpp:22
virtual void RemoveParent(Element *parent)
Remove a parent.
Definition Branch.cpp:105
virtual bool Intersects(wxRect2DDouble rect) const
Check if the element's rect intersects other rect.
Definition Branch.h:47
virtual bool SetNodeParent(Element *parent)
Set a perent to the node. If all conditions are met, a new parent are added to the element and the po...
Definition Branch.cpp:43
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
Definition Element.h:112
virtual bool Intersects(wxRect2DDouble rect) const =0
Check if the element's rect intersects other rect.
wxPoint2DDouble GetPosition() const
Get the element position.
Definition Element.h:186
double GetAngle() const
Get the element angle.
Definition Element.h:211
virtual wxPoint2DDouble RotateAtPosition(wxPoint2DDouble pointToRotate, double angle, bool degrees=true) const
Rotate a point as element position being the origin.
Definition Element.cpp:292
Abstract class of power elements.
virtual wxPoint2DDouble GetSwitchPoint(Element *parent, wxPoint2DDouble parentPoint, wxPoint2DDouble secondPoint) const
Get the correct switch position.