@@ -833,21 +833,27 @@ inline bool segments_intersect(const double &x1,
833833 // determinant
834834 double den = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
835835
836- if (isclose (den, 0.0 )) { // collinear segments
837- if (x1 == x2 && x2 == x3) { // segments have infinite slope (vertical lines)
838- // and lie on the same line
839- return (fmin (y1, y2) <= fmin (y3, y4) && fmin (y3, y4) <= fmax (y1, y2)) ||
840- (fmin (y3, y4) <= fmin (y1, y2) && fmin (y1, y2) <= fmax (y3, y4));
841- }
842- else {
843- double intercept = (y1*x2 - y2*x1)*(x4 - x3) - (y3*x4 - y4*x3)*(x1 - x2);
844- if (isclose (intercept, 0.0 )) { // segments lie on the same line
836+ // If den == 0 we have two possibilities:
837+ if (isclose (den, 0.0 )) {
838+ float t_area = (x2*y3 - x3*y2) - x1*(y3 - y2) + y1*(x3 - x2);
839+ // 1 - If the area of the triangle made by the 3 first points (2 from the first segment
840+ // plus one from the second) is zero, they are collinear
841+ if (isclose (t_area, 0.0 )) {
842+ if (x1 == x2 && x2 == x3) { // segments have infinite slope (vertical lines)
843+ // and lie on the same line
844+ return (fmin (y1, y2) <= fmin (y3, y4) && fmin (y3, y4) <= fmax (y1, y2)) ||
845+ (fmin (y3, y4) <= fmin (y1, y2) && fmin (y1, y2) <= fmax (y3, y4));
846+ }
847+ else {
845848 return (fmin (x1, x2) <= fmin (x3, x4) && fmin (x3, x4) <= fmax (x1, x2)) ||
846- (fmin (x3, x4) <= fmin (x1, x2) && fmin (x1, x2) <= fmax (x3, x4));
849+ (fmin (x3, x4) <= fmin (x1, x2) && fmin (x1, x2) <= fmax (x3, x4));
850+
847851 }
848852 }
849-
850- return false ;
853+ // 2 - If t_area is not zero, the segments are parallel, but not collinear
854+ else {
855+ return false ;
856+ }
851857 }
852858
853859 const double n1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
@@ -865,6 +871,7 @@ inline bool segments_intersect(const double &x1,
865871template <class PathIterator1 , class PathIterator2 >
866872bool path_intersects_path (PathIterator1 &p1, PathIterator2 &p2)
867873{
874+
868875 typedef PathNanRemover<py::PathIterator> no_nans_t ;
869876 typedef agg::conv_curve<no_nans_t > curve_t ;
870877
@@ -889,12 +896,14 @@ bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2)
889896 }
890897 c2.rewind (0 );
891898 c2.vertex (&x21, &y21);
899+
892900
893901 while (c2.vertex (&x22, &y22) != agg::path_cmd_stop) {
894902 // if the segment in path 2 is (almost) 0 length, skip to next vertex
895903 if ((isclose ((x21 - x22) * (x21 - x22) + (y21 - y22) * (y21 - y22), 0 ))){
896904 continue ;
897905 }
906+
898907 if (segments_intersect (x11, y11, x12, y12, x21, y21, x22, y22)) {
899908 return true ;
900909 }
0 commit comments