20#include "utils/DegreesAndRadians.h"
23Node::Node(wxPoint2DDouble position, NodeType nodeType,
double borderSize)
25 double totalRadius = m_radius + borderSize;
26 m_rect = wxRect2DDouble(position.m_x - totalRadius, position.m_y - totalRadius, totalRadius * 2, totalRadius * 2);
27 m_nodeType = nodeType;
29 m_triPts.push_back(GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, m_radius));
30 m_triPts.push_back(GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, -m_radius));
31 m_triPts.push_back(GetPosition() + wxPoint2DDouble(-m_radius + 1, 0));
35void Node::SetPosition(wxPoint2DDouble position)
37 m_rect = wxRect2DDouble(position.m_x - m_rect.m_width / 2, position.m_y - m_rect.m_height / 2, m_rect.m_width,
39 m_triPts[0] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, m_radius);
40 m_triPts[1] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, -m_radius);
41 m_triPts[2] = GetPosition() + wxPoint2DDouble(-m_radius + 1, 0);
44 if (m_angle != 0.0) RotateTriPt(m_angle);
47void Node::StartMove(wxPoint2DDouble position)
49 m_moveStartPt = position;
50 m_movePos = m_rect.GetPosition() - wxPoint2DDouble(-m_rect.m_width / 2, -m_rect.m_height / 2);
53void Node::Move(wxPoint2DDouble position) { SetPosition(m_movePos + position - m_moveStartPt); }
54wxPoint2DDouble Node::GetPosition()
const
56 return m_rect.GetPosition() + wxPoint2DDouble(m_rect.GetSize().GetWidth() / 2, m_rect.GetSize().GetHeight() / 2);
59void Node::RotateTriPt(
double angle)
61 double radAngle = wxDegToRad(angle);
62 wxPoint2DDouble rectCenter =
63 m_rect.GetPosition() + wxPoint2DDouble(m_rect.GetSize().GetWidth() / 2.0, m_rect.GetSize().GetHeight() / 2.0);
64 m_triPts[0] = wxPoint2DDouble(std::cos(radAngle) * (m_triPts[0].m_x - rectCenter.m_x) -
65 std::sin(radAngle) * (m_triPts[0].m_y - rectCenter.m_y) + rectCenter.m_x,
66 std::sin(radAngle) * (m_triPts[0].m_x - rectCenter.m_x) +
67 std::cos(radAngle) * (m_triPts[0].m_y - rectCenter.m_y) + rectCenter.m_y);
68 m_triPts[1] = wxPoint2DDouble(std::cos(radAngle) * (m_triPts[1].m_x - rectCenter.m_x) -
69 std::sin(radAngle) * (m_triPts[1].m_y - rectCenter.m_y) + rectCenter.m_x,
70 std::sin(radAngle) * (m_triPts[1].m_x - rectCenter.m_x) +
71 std::cos(radAngle) * (m_triPts[1].m_y - rectCenter.m_y) + rectCenter.m_y);
72 m_triPts[2] = wxPoint2DDouble(std::cos(radAngle) * (m_triPts[2].m_x - rectCenter.m_x) -
73 std::sin(radAngle) * (m_triPts[2].m_y - rectCenter.m_y) + rectCenter.m_x,
74 std::sin(radAngle) * (m_triPts[2].m_x - rectCenter.m_x) +
75 std::cos(radAngle) * (m_triPts[2].m_y - rectCenter.m_y) + rectCenter.m_y);
78void Node::Rotate(
bool clockwise)
90 m_triPts[0] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, m_radius);
91 m_triPts[1] = GetPosition() + wxPoint2DDouble(-m_radius - m_rect.GetSize().GetWidth() / 2, -m_radius);
92 m_triPts[2] = GetPosition() + wxPoint2DDouble(-m_radius + 1, 0);
95 if (m_angle != 0.0) RotateTriPt(m_angle);
98bool Node::Contains(wxPoint2DDouble position)
const
100 if (m_connected)
return false;
101 return m_rect.Contains(position);
104Node* Node::GetCopy()
const
111ControlElement::ControlElement(
int id) :
Element() { m_elementID = id; }
113ControlElement::~ControlElement()
126void ControlElement::DrawDCNodes(wxGraphicsContext* gc)
const
128 for (
auto node : m_nodeList) {
129 DrawDCCircle(node->GetPosition(), node->GetRadius(), 10, gc);
130 if (node->GetNodeType() == Node::NodeType::NODE_IN) {
DrawDCTriangle(node->GetInTrianglePts(), gc); }
136 m_moveStartPt = position;
137 m_movePos = m_position;
138 for (
int i = 0; i < (int)m_nodeList.size(); ++i) { m_nodeList[i]->StartMove(position); }
144 for (
int i = 0; i < (int)m_nodeList.size(); ++i) { m_nodeList[i]->Move(position); }
147bool ControlElement::Solve(
double* input,
double timeStep)
156void ControlElement::ReplaceNode(
Node* oldNode,
Node* newNode)
158 for (
unsigned int i = 0; i < m_nodeList.size(); i++) {
159 if (m_nodeList[i] == oldNode) m_nodeList[i] = newNode;
163ControlElement* ControlElement::GetControlElementFromID(std::vector< std::shared_ptr<ControlElement> > elementList,
int id)
165 for (
auto it = elementList.begin(), itEnd = elementList.end(); it != itEnd; ++it) {
167 if (element->
GetID() == id)
return element;
172void ControlElement::SaveControlNodes(rapidxml::xml_document<>& doc, rapidxml::xml_node<>* elementNode)
174 auto nodeList = XMLParser::AppendNode(doc, elementNode,
"NodeList");
176 for (
auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it) {
179 auto nodeN = XMLParser::AppendNode(doc, nodeList,
"Node");
180 XMLParser::SetNodeAttribute(doc, nodeN,
"ID",
id);
181 auto nodePosition = XMLParser::AppendNode(doc, nodeN,
"Position");
182 auto posNodeX = XMLParser::AppendNode(doc, nodePosition,
"X");
183 XMLParser::SetNodeValue(doc, posNodeX, node->GetPosition().m_x);
184 auto posNodeY = XMLParser::AppendNode(doc, nodePosition,
"Y");
185 XMLParser::SetNodeValue(doc, posNodeY, node->GetPosition().m_y);
186 auto angle = XMLParser::AppendNode(doc, nodeN,
"Angle");
187 XMLParser::SetNodeValue(doc, angle, node->GetAngle());
188 auto nodeType = XMLParser::AppendNode(doc, nodeN,
"Type");
189 XMLParser::SetNodeValue(doc, nodeType,
static_cast<int>(node->GetNodeType()));
194bool ControlElement::OpenControlNodes(rapidxml::xml_node<>* elementNode)
197 for (
auto it = m_nodeList.begin(), itEnd = m_nodeList.end(); it != itEnd; ++it)
delete* it;
200 auto nodeList = elementNode->first_node(
"NodeList");
201 if (!nodeList)
return false;
202 auto nodeN = nodeList->first_node(
"Node");
204 auto nodePosition = nodeN->first_node(
"Position");
205 double nodePosX = XMLParser::GetNodeValueDouble(nodePosition,
"X");
206 double nodePosY = XMLParser::GetNodeValueDouble(nodePosition,
"Y");
207 double nodeAngle = XMLParser::GetNodeValueDouble(nodeN,
"Angle");
208 Node::NodeType nodeType =
static_cast<Node::NodeType
>(XMLParser::GetNodeValueInt(nodeN,
"Type"));
209 Node* node =
new Node(wxPoint2DDouble(nodePosX, nodePosY), nodeType, 2.0);
210 node->SetAngle(nodeAngle);
211 m_nodeList.push_back(node);
212 nodeN = nodeN->next_sibling(
"Node");
217bool ControlElement::Initialize()
Base class of a control element. Provide general methods to other control classes.
virtual void StartMove(wxPoint2DDouble position)
Update the element attributes related to the movement.
virtual void Move(wxPoint2DDouble position)
Move the element other position.
Base class of all elements of the program. This class is responsible for manage graphical and his dat...
virtual int GetID() const
Get the element ID.
void SetPosition(const wxPoint2DDouble position)
Set the element position and update the rectangle.
virtual void DrawDCTriangle(std::vector< wxPoint2DDouble > points, wxGraphicsContext *gc) const
Draw rectangle.
virtual void DrawDCCircle(wxPoint2DDouble position, double radius, int numSegments, wxGraphicsContext *gc) const
Draw a circle using device context.
Node of a control element. This class manages the user interaction with the connection and control el...