]> Shamusworld >> Repos - architektonas/blobdiff - src/geometry.cpp
More miscellaneous changes.
[architektonas] / src / geometry.cpp
index 86d1906f764851e7b28b5172292ab60aaac1b4f9..31c5257d8d0aa9f39c5924224f11d40359191d7e 100644 (file)
@@ -44,7 +44,7 @@ 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 ||
+       // || (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)
@@ -143,14 +143,37 @@ void Geometry::CheckLineToLineIntersection(Object * l1, Object * l2)
        double rxs = (r.x * s.y) - (s.x * r.y);
        double t, u;
 
+       // The angle is zero, so the lines probably overlap, or are parallel.  Either way, there is either INFINITE intersections, or zero.  Either way, the result is useless to us.  It does present a bit of an inconsistency though: lines connected at their endpoints that aren't at a zero angle will show as overlapping (the only case this could even REMOTELY be useful is when the angle between is 180°--not zero, as zero is the degenerate case).  :-P
        if (rxs == 0)
        {
-               double qpxr = (v1.x * r.y) - (r.x * v1.y);
+// WHY would you do this???  The lines overlap at an INFINITE number of points!
+// The assumption is that the angle is 180°, not 0°.
+               // If we want to detect the degenerate case, we can check the parameter of the endpoints of the one line to the other.  If any of the parameters are in (0, 1), then it's the degenerate case (we would check the endpoints of the shorter segment against the longer).
+/*             double qpxr = (v1.x * r.y) - (r.x * v1.y);
 
-               // Lines are parallel, so no intersection...
+               // Line segments are parallel, so no intersection...
                if (qpxr != 0)
                        return;
 
+               // Otherwise, the segments are colinear.  Need to check for the 0° (degenerate) vs the 180° (OK) case.
+               Object * larger = l1;
+               Object * smaller = l2;
+
+               if (r->Magnitude() < s->Magnitude())
+               {
+                       larger = l2;
+                       smaller = l1;
+               }
+
+               double param1 = ParameterOfLineAndPoint(larger->p[0], larger->p[1], smaller->p[0]);
+               double param2 = ParameterOfLineAndPoint(larger->p[0], larger->p[1], smaller->p[1]);
+
+               // Check for the degenerate case, and return if found
+               if ((param1 > 0 && param1 < 1.0) || (param2 > 0 && param2 < 1.0))
+                       return;
+
+////   or just use AngleBetween: Nah, won't work...
+
                // Check to see which endpoints are connected... Four possibilities:
                if (l1->p[0] == l2->p[0])
                        t = 0, u = 0;
@@ -160,7 +183,7 @@ void Geometry::CheckLineToLineIntersection(Object * l1, Object * l2)
                        t = 1.0, u = 0;
                else if (l1->p[1] == l2->p[1])
                        t = 1.0, u = 1.0;
-               else
+               else*/
                        return;
        }
        else
@@ -169,12 +192,24 @@ void Geometry::CheckLineToLineIntersection(Object * l1, Object * l2)
                u = ((v1.x * r.y) - (r.x * v1.y)) / rxs;
        }
 
+       // Check that the parameters are above the epsilon, otherwise clamp them to
+       // zero or one, as the case may be
+       if (fabs(t) < EPSILON)
+               t = 0;
+       else if (fabs(1.0 - t) < EPSILON)
+               t = 1.0;
+
+       if (fabs(u) < EPSILON)
+               u = 0;
+       else if (fabs(1.0 - u) < EPSILON)
+               u = 1.0;
+
        Global::intersectParam[0] = t;
        Global::intersectParam[1] = u;
 
        // If the parameters are in range, we have overlap!
        if ((t >= 0) && (t <= 1.0) && (u >= 0) && (u <= 1.0))
-               Global::numIntersectParams = 1;
+               Global::numIntersectParams = 2;
 }
 
 void Geometry::CheckCircleToCircleIntersection(Object * c1, Object * c2)