]> Shamusworld >> Repos - architektonas/blobdiff - src/geometry.cpp
GUI functionality fixes.
[architektonas] / src / geometry.cpp
index b9158974ec97d902d4ff2e936a2cc4b43e469082..95d12c65068b16715086191e1d70c7e01483dcbd 100644 (file)
@@ -39,6 +39,29 @@ double Geometry::ParameterOfLineAndPoint(Point tail, Point head, Point point)
 }
 
 
+double Geometry::DistanceToLineFromPoint(Point tail, Point head, Point point)
+{
+       // Interpretation: given a line in the form x = a + tu, where u is the
+       // unit vector of the line, a is the tail and t is a parameter which
+       // describes the line, the distance of a point p to the line is given by:
+       // || (a - p) - ((a - p) . u) u ||
+       // We go an extra step: we set the sign to reflect which side of the line
+       // it's on (+ == to the left if head points away from you, - == to the
+       // right)
+       Vector line(tail, head);
+       Vector u = line.Unit();
+       Vector a_p = tail - point;
+       Vector dist = a_p - (u * (a_p).Dot(u));
+
+       double angle = Vector::Angle(tail, point) - line.Angle();
+
+       if (angle < 0)
+               angle += TAU;
+
+       return dist.Magnitude() * (angle < HALF_TAU ? +1.0 : -1.0);
+}
+
+
 Point Geometry::MirrorPointAroundLine(Point point, Point tail, Point head)
 {
        // Get the vector of the intersection of the line and the normal on the
@@ -255,14 +278,12 @@ void Geometry::CheckLineToCircleIntersection(Object * l, Object * c)
        // Radius is the hypotenuse, so we have to use c² = a² + b² => a² = c² - b²
        double perpendicularLength = sqrt((c->radius[0] * c->radius[0]) - (distance * distance));
 
-       // Now, find the points using the length, then check to see if they are on
-       // the line segment
+       // Now, find the intersection points using the length...
        Vector lineUnit = Vector(l->p[0], l->p[1]).Unit();
        Point i1 = p + (lineUnit * perpendicularLength);
        Point i2 = p - (lineUnit * perpendicularLength);
 
-       // Now we have our intersection points, next we need to see if they are on
-       // the line segment...
+       // Next we need to see if they are on the line segment...
        double u = ParameterOfLineAndPoint(l->p[0], l->p[1], i1);
        double v = ParameterOfLineAndPoint(l->p[0], l->p[1], i2);
 
@@ -342,3 +363,22 @@ Point Geometry::GetPointForParameter(Object * obj, double t)
        return Point(0, 0);
 }
 
+
+Point Geometry::Midpoint(Line * line)
+{
+       return Point((line->p[0].x + line->p[1].x) / 2.0,
+               (line->p[0].y + line->p[1].y) / 2.0);
+}
+
+
+/*
+How to find the tangent of a point off a circle:
+
+ •  Calculate the midpoint on the point and the center of the circle
+ •  Get the length of the line segment from the and the center divided by two
+ •  Use that length to construct a circle with the point at the center and the
+    radius equal to that length
+ •  The intersection of the two circles are the tangent points
+
+*/
+