From 8f475833e585692544cb0f481b0dce0c3439a1a9 Mon Sep 17 00:00:00 2001 From: Thales Lima Oliveira Date: Wed, 31 Aug 2016 23:09:16 -0300 Subject: Transformer complete --- Project/Element.cpp | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 102 insertions(+), 3 deletions(-) (limited to 'Project/Element.cpp') diff --git a/Project/Element.cpp b/Project/Element.cpp index 7f0e211..d00837a 100644 --- a/Project/Element.cpp +++ b/Project/Element.cpp @@ -103,8 +103,107 @@ wxPoint2DDouble Element::WorldToScreen(wxPoint2DDouble translation, double scale scale; } -wxPoint2DDouble Element::WorldToScreen(wxPoint2DDouble position, wxPoint2DDouble translation, double scale, double offsetX, double offsetY) const +wxPoint2DDouble Element::WorldToScreen(wxPoint2DDouble position, + wxPoint2DDouble translation, + double scale, + double offsetX, + double offsetY) const { - return wxPoint2DDouble(position.m_x + offsetX + translation.m_x, position.m_y + offsetY + translation.m_y) * - scale; + return wxPoint2DDouble(position.m_x + offsetX + translation.m_x, position.m_y + offsetY + translation.m_y) * scale; +} + +void Element::DrawPoint(wxPoint2DDouble position, double size) const +{ + glPointSize(size); + glBegin(GL_POINTS); + glVertex2d(position.m_x, position.m_y); + glEnd(); +} + +bool Element::RotatedRectanglesIntersects(wxRect2DDouble rect1, + wxRect2DDouble rect2, + double angle1, + double angle2) const +{ + wxPoint2DDouble rect1Corners[4] = {rect1.GetLeftTop(), rect1.GetLeftBottom(), rect1.GetRightBottom(), + rect1.GetRightTop()}; + wxPoint2DDouble rect2Corners[4] = {rect2.GetLeftTop(), rect2.GetLeftBottom(), rect2.GetRightBottom(), + rect2.GetRightTop()}; + wxPoint2DDouble rect1Center(rect1.m_x + rect1.m_width / 2.0, rect1.m_y + rect1.m_height / 2.0); + wxPoint2DDouble rect2Center(rect2.m_x + rect2.m_width / 2.0, rect2.m_y + rect2.m_height / 2.0); + + // Rotate the corners. + double radAngle1 = wxDegToRad(angle1); + double radAngle2 = wxDegToRad(angle2); + + for(int i = 0; i < 4; i++) { + rect1Corners[i] = + wxPoint2DDouble(std::cos(radAngle1) * (rect1Corners[i].m_x - rect1Center.m_x) - + std::sin(radAngle1) * (rect1Corners[i].m_y - rect1Center.m_y) + rect1Center.m_x, + std::sin(radAngle1) * (rect1Corners[i].m_x - rect1Center.m_x) + + std::cos(radAngle1) * (rect1Corners[i].m_y - rect1Center.m_y) + rect1Center.m_y); + + rect2Corners[i] = + wxPoint2DDouble(std::cos(radAngle2) * (rect2Corners[i].m_x - rect2Center.m_x) - + std::sin(radAngle2) * (rect2Corners[i].m_y - rect2Center.m_y) + rect2Center.m_x, + std::sin(radAngle2) * (rect2Corners[i].m_x - rect2Center.m_x) + + std::cos(radAngle2) * (rect2Corners[i].m_y - rect2Center.m_y) + rect2Center.m_y); + } + + //[Ref] http://www.gamedev.net/page/resources/_/technical/game-programming/2d-rotated-rectangle-collision-r2604 + + // Find the rectangles axis to project + wxPoint2DDouble axis[4] = {rect1Corners[3] - rect1Corners[0], rect1Corners[3] - rect1Corners[2], + rect2Corners[3] - rect2Corners[0], rect2Corners[3] - rect2Corners[2]}; + + // Calculate the projected points to each axis + wxPoint2DDouble rect1ProjPts[4][4]; // [axis][corner] + wxPoint2DDouble rect2ProjPts[4][4]; // [axis][corner] + for(int i = 0; i < 4; i++) { + double den = axis[i].m_x * axis[i].m_x + axis[i].m_y * axis[i].m_y; + for(int j = 0; j < 4; j++) { + double m_rectProj = (rect1Corners[j].m_x * axis[i].m_x + rect1Corners[j].m_y * axis[i].m_y) / den; + double rectProj = (rect2Corners[j].m_x * axis[i].m_x + rect2Corners[j].m_y * axis[i].m_y) / den; + + rect1ProjPts[i][j] = wxPoint2DDouble(m_rectProj * axis[i].m_x, m_rectProj * axis[i].m_y); + rect2ProjPts[i][j] = wxPoint2DDouble(rectProj * axis[i].m_x, rectProj * axis[i].m_y); + } + } + + // Calculate the scalar value to identify the max and min values on projections + double rect1Scalar[4][4]; //[axis][corner] + double rect2Scalar[4][4]; //[axis][corner] + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 4; j++) { + rect1Scalar[i][j] = rect1ProjPts[i][j].m_x * axis[i].m_x + rect1ProjPts[i][j].m_y * axis[i].m_y; + rect2Scalar[i][j] = rect2ProjPts[i][j].m_x * axis[i].m_x + rect2ProjPts[i][j].m_y * axis[i].m_y; + } + } + // Identify the max and min scalar values + double rect1Min[4]; + double rect1Max[4]; + double rect2Min[4]; + double rect2Max[4]; + + for(int i = 0; i < 4; i++) { + rect1Max[i] = rect1Scalar[i][0]; + rect2Max[i] = rect2Scalar[i][0]; + rect1Min[i] = rect1Scalar[i][0]; + rect2Min[i] = rect2Scalar[i][0]; + + for(int j = 1; j < 4; j++) { + if(rect1Max[i] < rect1Scalar[i][j]) rect1Max[i] = rect1Scalar[i][j]; + if(rect2Max[i] < rect2Scalar[i][j]) rect2Max[i] = rect2Scalar[i][j]; + + if(rect1Min[i] > rect1Scalar[i][j]) rect1Min[i] = rect1Scalar[i][j]; + if(rect2Min[i] > rect2Scalar[i][j]) rect2Min[i] = rect2Scalar[i][j]; + } + } + + // Check if any segment don't overlap + for(int i = 0; i < 4; i++) { + if(!(rect2Min[i] <= rect1Max[i] && rect2Max[i] >= rect1Min[i])) return false; + } + + return true; } -- cgit