+// geometry.cpp: Algebraic geometry helper functions
+//
+// Part of the Architektonas Project
+// (C) 2011 Underground Software
+// See the README and GPLv3 files for licensing and warranty information
+//
+// JLH = James Hammons <jlhamm@acm.org>
+//
+// WHO WHEN WHAT
+// --- ---------- ------------------------------------------------------------
+// JLH 08/31/2011 Created this file
+//
+// NOTE: All methods in this class are static.
+//
+
+#include "geometry.h"
+
+
+Point Geometry::IntersectionOfLineAndLine(Point p1, Point p2, Point p3, Point p4)
+{
+ // Find the intersection of the lines by formula:
+ // px = (x1y2 - y1x2)(x3 - x4) - (x1 - x2)(x3y4 - y3x4)
+ // py = (x1y2 - y1x2)(y3 - y4) - (y1 - y2)(x3y4 - y3x4)
+ // d = (x1 - x2)(y3 - y4) - (y1 - y2)(x3 - x4) = 0 if lines are parallel
+ // Intersection is (px / d, py / d)
+
+ double d = ((p1.x - p2.x) * (p3.y - p4.y)) - ((p1.y - p2.y) * (p3.x - p4.x));
+
+ // Check for parallel lines, and return sentinel if so
+ if (d == 0)
+ return Point(0, 0, -1);
+
+ double px = (((p1.x * p2.y) - (p1.y * p2.x)) * (p3.x - p4.x))
+ - ((p1.x - p2.x) * ((p3.x * p4.y) - (p3.y * p4.x)));
+ double py = (((p1.x * p2.y) - (p1.y * p2.x)) * (p3.y - p4.y))
+ - ((p1.y - p2.y) * ((p3.x * p4.y) - (p3.y * p4.x)));
+
+ return Point(px / d, py / d, 0);
+}
+
+
+// Returns the parameter of a point in space to this vector. If the parameter
+// is between 0 and 1, the normal of the vector to the point is on the vector.
+double Geometry::ParameterOfLineAndPoint(Point lp1, Point lp2, Point point)
+{
+ // Geometric interpretation:
+ // The parameterized point on the vector lineSegment is where the normal of
+ // the lineSegment to the point intersects lineSegment. If the pp < 0, then
+ // the perpendicular lies beyond the 1st endpoint. If pp > 1, then the
+ // perpendicular lies beyond the 2nd endpoint.
+
+ Vector lineSegment = lp1 - lp2;
+ double magnitude = lineSegment.Magnitude();
+ Vector pointSegment = point - lp2;
+ double t = lineSegment.Dot(pointSegment) / (magnitude * magnitude);
+ return t;
+}
+
+
+Point Geometry::MirrorPointAroundLine(Point point, Point p1, Point p2)
+{
+ // Get the vector of the intersection of the line and the normal on the
+ // line to the point in question.
+ double t = ParameterOfLineAndPoint(p1, p2, point);
+ Vector v = Vector(p1, p2) * t;
+
+ // Get the point normal to point to the line passed in (p2 is the tail)
+ Point normalOnLine = p2 + v;
+
+ // Make our mirrored vector (head - tail)
+ Vector mirror = -(point - normalOnLine);
+
+ // Find the mirrored point
+ Point mirroredPoint = normalOnLine + mirror;
+
+ return mirroredPoint;
+}
+