@@ -838,21 +838,27 @@ inline bool segments_intersect(const double &x1,
838
838
// determinant
839
839
double den = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1 ));
840
840
841
- if (isclose (den, 0.0 )) { // collinear segments
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 {
848
- double intercept = (y1 *x2 - y2*x1)*(x4 - x3) - (y3*x4 - y4*x3)*(x1 - x2);
849
- if (isclose (intercept, 0.0 )) { // segments lie on the same line
841
+ // If den == 0 we have two possibilities:
842
+ if (isclose (den, 0.0 )) {
843
+ float t_area = (x2*y3 - x3*y2) - x1*(y3 - y2) + y1 *(x3 - x2);
844
+ // 1 - If the area of the triangle made by the 3 first points (2 from the first segment
845
+ // plus one from the second) is zero, they are collinear
846
+ if (isclose (t_area, 0.0 )) {
847
+ if (x1 == x2 && x2 == x3) { // segments have infinite slope (vertical lines)
848
+ // and lie on the same line
849
+ return (fmin (y1 , y2) <= fmin (y3, y4) && fmin (y3, y4) <= fmax (y1 , y2)) ||
850
+ (fmin (y3, y4) <= fmin (y1 , y2) && fmin (y1 , y2) <= fmax (y3, y4));
851
+ }
852
+ else {
850
853
return (fmin (x1, x2) <= fmin (x3, x4) && fmin (x3, x4) <= fmax (x1, x2)) ||
851
- (fmin (x3, x4) <= fmin (x1, x2) && fmin (x1, x2) <= fmax (x3, x4));
854
+ (fmin (x3, x4) <= fmin (x1, x2) && fmin (x1, x2) <= fmax (x3, x4));
855
+
852
856
}
853
857
}
854
-
855
- return false ;
858
+ // 2 - If t_area is not zero, the segments are parallel, but not collinear
859
+ else {
860
+ return false ;
861
+ }
856
862
}
857
863
858
864
const double n1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
@@ -870,6 +876,7 @@ inline bool segments_intersect(const double &x1,
870
876
template <class PathIterator1 , class PathIterator2 >
871
877
bool path_intersects_path (PathIterator1 &p1, PathIterator2 &p2)
872
878
{
879
+
873
880
typedef PathNanRemover<py::PathIterator> no_nans_t ;
874
881
typedef agg::conv_curve<no_nans_t > curve_t ;
875
882
@@ -894,12 +901,14 @@ bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2)
894
901
}
895
902
c2.rewind (0 );
896
903
c2.vertex (&x21, &y21);
904
+
897
905
898
906
while (c2.vertex (&x22, &y22) != agg::path_cmd_stop) {
899
907
// if the segment in path 2 is (almost) 0 length, skip to next vertex
900
908
if ((isclose ((x21 - x22) * (x21 - x22) + (y21 - y22) * (y21 - y22), 0 ))){
901
909
continue ;
902
910
}
911
+
903
912
if (segments_intersect (x11, y11, x12, y12, x21, y21, x22, y22)) {
904
913
return true ;
905
914
}
0 commit comments