From b5324f48c855b0c82ccf6da7d5a008fe5cf1c17e Mon Sep 17 00:00:00 2001 From: Thales1330 Date: Mon, 8 Aug 2016 17:01:53 -0300 Subject: Start Power Line implementation gogogogo --- Project/Line.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Project/Line.cpp (limited to 'Project/Line.cpp') diff --git a/Project/Line.cpp b/Project/Line.cpp new file mode 100644 index 0000000..5879555 --- /dev/null +++ b/Project/Line.cpp @@ -0,0 +1,12 @@ +#include "Line.h" + +Line::Line() {} +Line::~Line() {} +bool Line::Contains(wxPoint2DDouble position) const {} +void Line::Draw(wxPoint2DDouble translation, double scale) const {} +wxCursor Line::GetBestPickboxCursor() const {} +void Line::Insert(Element* parent, wxPoint2DDouble position) {} +bool Line::Intersects(wxRect2DDouble rect) const {} +void Line::MovePickbox(wxPoint2DDouble position) {} +bool Line::PickboxContains(wxPoint2DDouble position) {} +void Line::Rotate() {} -- cgit From 0a85e05fa7aa0e2b950c2c3bcec5d45f25b1c0e2 Mon Sep 17 00:00:00 2001 From: Thales1330 Date: Tue, 9 Aug 2016 17:45:09 -0300 Subject: Line under implementation --- Project/Line.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'Project/Line.cpp') diff --git a/Project/Line.cpp b/Project/Line.cpp index 5879555..d0df0a2 100644 --- a/Project/Line.cpp +++ b/Project/Line.cpp @@ -2,11 +2,33 @@ Line::Line() {} Line::~Line() {} -bool Line::Contains(wxPoint2DDouble position) const {} +bool Line::Contains(wxPoint2DDouble position) const { return false; } void Line::Draw(wxPoint2DDouble translation, double scale) const {} -wxCursor Line::GetBestPickboxCursor() const {} -void Line::Insert(Element* parent, wxPoint2DDouble position) {} -bool Line::Intersects(wxRect2DDouble rect) const {} +wxCursor Line::GetBestPickboxCursor() const { return wxCURSOR_ARROW; } +bool Line::AddParent(Element* parent, wxPoint2DDouble position) +{ + if(parent) { + if(m_parentList.size() == 0) { + m_parentList.push_back(parent); + m_pointList.push_back(position); // First point + return false; + } + else if(parent != m_parentList[0]) + { + m_parentList.push_back(parent); + m_pointList.push_back(position); // Last point + return true; + } + } + return false; +} +bool Line::Intersects(wxRect2DDouble rect) const { return false; } void Line::MovePickbox(wxPoint2DDouble position) {} -bool Line::PickboxContains(wxPoint2DDouble position) {} +bool Line::PickboxContains(wxPoint2DDouble position) { return false; } void Line::Rotate() {} +void Line::AddPoint(wxPoint2DDouble point) +{ + if(m_parentList.size() != 0) { + m_pointList.push_back(point); + } +} -- cgit From e58cec073cbd982246898c733ae21b9f2b92b2b7 Mon Sep 17 00:00:00 2001 From: Thales1330 Date: Wed, 17 Aug 2016 17:19:58 -0300 Subject: Line under implementation --- Project/Line.cpp | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) (limited to 'Project/Line.cpp') diff --git a/Project/Line.cpp b/Project/Line.cpp index d0df0a2..b8686bb 100644 --- a/Project/Line.cpp +++ b/Project/Line.cpp @@ -3,20 +3,69 @@ Line::Line() {} Line::~Line() {} bool Line::Contains(wxPoint2DDouble position) const { return false; } -void Line::Draw(wxPoint2DDouble translation, double scale) const {} +void Line::Draw(wxPoint2DDouble translation, double scale) const +{ + std::vector pointList = m_pointList; + if(!m_inserted && pointList.size() > 0) { + wxPoint2DDouble secondPoint = m_position; + if(pointList.size() > 2) { + secondPoint = pointList[2]; + } + pointList[1] = GetSwitchPoint(m_parentList[0], pointList[0], secondPoint); + pointList.push_back(m_position); + } + + glLineWidth(1.5); + glColor4d(0.2, 0.2, 0.2, 1.0); + DrawLine(pointList); + + // Draw nodes. + if(pointList.size() > 0) { + glColor4d(0.2, 0.2, 0.2, 1.0); + DrawCircle(pointList[0], 5.0, 10, GL_POLYGON); + if(m_inserted) { + DrawCircle(pointList[pointList.size() - 1], 5.0, 10, GL_POLYGON); + } + } +} + wxCursor Line::GetBestPickboxCursor() const { return wxCURSOR_ARROW; } bool Line::AddParent(Element* parent, wxPoint2DDouble position) { if(parent) { + // First bus. if(m_parentList.size() == 0) { + m_position = position; m_parentList.push_back(parent); - m_pointList.push_back(position); // First point + wxPoint2DDouble parentPt = parent->RotateAtPosition( + position, -parent->GetAngle()); // Rotate click to horizontal position. + parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus. + parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back. + m_pointList.push_back(parentPt); // First point + m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_position)); return false; } + // Second bus. else if(parent != m_parentList[0]) { m_parentList.push_back(parent); - m_pointList.push_back(position); // Last point + wxPoint2DDouble parentPt = parent->RotateAtPosition( + position, -parent->GetAngle()); // Rotate click to horizontal position. + parentPt.m_y = parent->GetPosition().m_y; // Centralize on bus. + parentPt = parent->RotateAtPosition(parentPt, parent->GetAngle()); // Rotate back. + + // Set first switch point. + wxPoint2DDouble secondPoint = parentPt; + if(m_pointList.size() > 2) { + secondPoint = m_pointList[2]; + } + m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], secondPoint); + + // Set the second switch point. + m_pointList.push_back(GetSwitchPoint(parent, parentPt, m_pointList[m_pointList.size() - 1])); + + m_pointList.push_back(parentPt); // Last point. + m_inserted = true; return true; } } @@ -32,3 +81,20 @@ void Line::AddPoint(wxPoint2DDouble point) m_pointList.push_back(point); } } + +void Line::MoveNode(Element* parent, wxPoint2DDouble position) +{ + // First bus. + if(parent == m_parentList[0]) { + m_pointList[0] = parent->GetMovePosition() + position - parent->GetMoveStartPosition(); + } + // Second bus. + else if(parent == m_parentList[1]) + { + m_pointList[m_pointList.size() - 1] = parent->GetMovePosition() + position - parent->GetMoveStartPosition(); + } + // Recalculate switches positions + m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], m_pointList[2]); + m_pointList[m_pointList.size() - 2] = + GetSwitchPoint(m_parentList[1], m_pointList[m_pointList.size() - 1], m_pointList[m_pointList.size() - 3]); +} -- cgit From 05525745c0b0d189484da3c45f95356d7558e2cf Mon Sep 17 00:00:00 2001 From: Thales1330 Date: Thu, 18 Aug 2016 19:10:04 -0300 Subject: Line improvements, context menu implemented Line still under construction, contex menu base implemented --- Project/Line.cpp | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 143 insertions(+), 8 deletions(-) (limited to 'Project/Line.cpp') diff --git a/Project/Line.cpp b/Project/Line.cpp index b8686bb..54418d4 100644 --- a/Project/Line.cpp +++ b/Project/Line.cpp @@ -2,7 +2,14 @@ Line::Line() {} Line::~Line() {} -bool Line::Contains(wxPoint2DDouble position) const { return false; } +bool Line::Contains(wxPoint2DDouble position) const +{ + if(PointToLineDistance(position) < 5.0) { + return true; + } + return false; +} + void Line::Draw(wxPoint2DDouble translation, double scale) const { std::vector pointList = m_pointList; @@ -15,6 +22,22 @@ void Line::Draw(wxPoint2DDouble translation, double scale) const pointList.push_back(m_position); } + // Line selected (Layer 1). + if(m_selected) { + glLineWidth(1.5 + m_borderSize * 2.0); + glColor4d(0.0, 0.5, 1.0, 0.5); + DrawLine(pointList); + + // Draw nodes selection. + if(pointList.size() > 0) { + DrawCircle(pointList[0], 5.0 + m_borderSize, 10, GL_POLYGON); + if(m_inserted) { + DrawCircle(pointList[pointList.size() - 1], 5.0 + +m_borderSize, 10, GL_POLYGON); + } + } + } + + // Draw line (Layer 2) glLineWidth(1.5); glColor4d(0.2, 0.2, 0.2, 1.0); DrawLine(pointList); @@ -27,9 +50,21 @@ void Line::Draw(wxPoint2DDouble translation, double scale) const DrawCircle(pointList[pointList.size() - 1], 5.0, 10, GL_POLYGON); } } + + // Draw pickboxes (Layer 3). + if(m_showPickbox) { + glPushMatrix(); + glLoadIdentity(); + + for(int i = 2; i < (int)m_pointList.size() - 2; i++) { + DrawPickbox(WorldToScreen(m_pointList[i], translation, scale)); + } + + glPopMatrix(); + } } -wxCursor Line::GetBestPickboxCursor() const { return wxCURSOR_ARROW; } +wxCursor Line::GetBestPickboxCursor() const { return wxCURSOR_SIZING; } bool Line::AddParent(Element* parent, wxPoint2DDouble position) { if(parent) { @@ -71,10 +106,48 @@ bool Line::AddParent(Element* parent, wxPoint2DDouble position) } return false; } -bool Line::Intersects(wxRect2DDouble rect) const { return false; } -void Line::MovePickbox(wxPoint2DDouble position) {} -bool Line::PickboxContains(wxPoint2DDouble position) { return false; } -void Line::Rotate() {} +bool Line::Intersects(wxRect2DDouble rect) const +{ + for(auto it = m_pointList.begin(); it != m_pointList.end(); ++it) { + if(rect.Contains(*it)) return true; + } + return false; +} +void Line::MovePickbox(wxPoint2DDouble position) +{ + if(m_activePickboxID == ID_PB_NONE) return; + + for(int i = 2; i < (int)m_pointList.size() - 2; i++) { + if(m_activePickboxID == i) { + m_pointList[i] = m_movePts[i] + position - m_moveStartPt; + UpdateSwitchesPosition(); + } + } +} +bool Line::PickboxContains(wxPoint2DDouble position) +{ + for(int i = 2; i < (int)m_pointList.size() - 2; i++) { + wxRect2DDouble rect(m_pointList[i].m_x - 5.0, m_pointList[i].m_y - 5.0, 10.0, 10.0); + if(rect.Contains(position)) { + m_activePickboxID = i; + return true; + } + } + return false; +} +void Line::RotateNode(Element* parent) +{ + if(parent == m_parentList[0]) { + m_pointList[0] = parent->RotateAtPosition(m_pointList[0], m_rotationAngle); + } + else if(parent == m_parentList[1]) + { + m_pointList[m_pointList.size() - 1] = + parent->RotateAtPosition(m_pointList[m_pointList.size() - 1], m_rotationAngle); + } + UpdateSwitchesPosition(); +} + void Line::AddPoint(wxPoint2DDouble point) { if(m_parentList.size() != 0) { @@ -82,19 +155,81 @@ void Line::AddPoint(wxPoint2DDouble point) } } +void Line::StartMove(wxPoint2DDouble position) +{ + m_moveStartPt = position; + m_movePts = m_pointList; +} + void Line::MoveNode(Element* parent, wxPoint2DDouble position) { // First bus. if(parent == m_parentList[0]) { - m_pointList[0] = parent->GetMovePosition() + position - parent->GetMoveStartPosition(); + m_pointList[0] = m_movePts[0] + position - m_moveStartPt; } // Second bus. else if(parent == m_parentList[1]) { - m_pointList[m_pointList.size() - 1] = parent->GetMovePosition() + position - parent->GetMoveStartPosition(); + m_pointList[m_pointList.size() - 1] = m_movePts[m_pointList.size() - 1] + position - m_moveStartPt; } + + // If the line is selected, move all the points, except the switches and buses points. + if(m_selected) { + for(int i = 2; i < (int)m_pointList.size() - 2; i++) { + m_pointList[i] = m_movePts[i] + position - m_moveStartPt; + } + } + // Recalculate switches positions + UpdateSwitchesPosition(); +} + +void Line::UpdateSwitchesPosition() +{ m_pointList[1] = GetSwitchPoint(m_parentList[0], m_pointList[0], m_pointList[2]); m_pointList[m_pointList.size() - 2] = GetSwitchPoint(m_parentList[1], m_pointList[m_pointList.size() - 1], m_pointList[m_pointList.size() - 3]); } + +double Line::PointToLineDistance(wxPoint2DDouble point) const +{ + //[Ref] http://geomalgorithms.com/a02-_lines.html + double distance = 100.0; // Big initial distance. + wxPoint2DDouble p0 = point; + + for(int i = 0; i < (int)m_pointList.size() - 1; i++) { + double d = 0.0; + + wxPoint2DDouble p1 = m_pointList[i]; + wxPoint2DDouble p2 = m_pointList[i + 1]; + + wxPoint2DDouble v = p2 - p1; + wxPoint2DDouble w = p0 - p1; + + double c1 = w.m_x * v.m_x + w.m_y * v.m_y; + double c2 = v.m_x * v.m_x + v.m_y * v.m_y; + + if(c1 <= 0.0) { + d = std::sqrt(std::pow(p0.m_y - p1.m_y, 2) + std::pow(p0.m_x - p1.m_x, 2)); + } + else if(c2 <= c1) + { + d = std::sqrt(std::pow(p0.m_y - p2.m_y, 2) + std::pow(p0.m_x - p2.m_x, 2)); + } + else + { + d = std::abs((p2.m_y - p1.m_y) * p0.m_x - (p2.m_x - p1.m_x) * p0.m_y + p2.m_x * p1.m_y - + p2.m_y * p1.m_x) / + std::sqrt(std::pow(p2.m_y - p1.m_y, 2) + std::pow(p2.m_x - p1.m_x, 2)); + } + if(d < distance) distance = d; + } + + return distance; +} + +bool Line::GetContextMenu(wxMenu& menu) +{ + menu.Append(ID_EDIT_LINE, _("Edit line")); + return true; +} -- cgit