@@ -833,21 +833,27 @@ inline bool segments_intersect(const double &x1,
833
833
// determinant
834
834
double den = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1 ));
835
835
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 {
845
848
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
+
847
851
}
848
852
}
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
+ }
851
857
}
852
858
853
859
const double n1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
@@ -865,6 +871,7 @@ inline bool segments_intersect(const double &x1,
865
871
template <class PathIterator1 , class PathIterator2 >
866
872
bool path_intersects_path (PathIterator1 &p1, PathIterator2 &p2)
867
873
{
874
+
868
875
typedef PathNanRemover<py::PathIterator> no_nans_t ;
869
876
typedef agg::conv_curve<no_nans_t > curve_t ;
870
877
@@ -889,12 +896,14 @@ bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2)
889
896
}
890
897
c2.rewind (0 );
891
898
c2.vertex (&x21, &y21);
899
+
892
900
893
901
while (c2.vertex (&x22, &y22) != agg::path_cmd_stop) {
894
902
// if the segment in path 2 is (almost) 0 length, skip to next vertex
895
903
if ((isclose ((x21 - x22) * (x21 - x22) + (y21 - y22) * (y21 - y22), 0 ))){
896
904
continue ;
897
905
}
906
+
898
907
if (segments_intersect (x11, y11, x12, y12, x21, y21, x22, y22)) {
899
908
return true ;
900
909
}
0 commit comments