public override int ComputeIntersect(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) { IsProper = false; // first try a fast test to see if the envelopes of the lines intersect if (!Envelope.Intersects(p1, p2, q1, q2)) { return(NoIntersection); } // for each endpoint, compute which side of the other segment it lies // if both endpoints lie on the same side of the other segment, // the segments do not intersect var Pq1 = Orientation.Index(p1, p2, q1); var Pq2 = Orientation.Index(p1, p2, q2); if ((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { return(NoIntersection); } var Qp1 = Orientation.Index(q1, q2, p1); var Qp2 = Orientation.Index(q1, q2, p2); if ((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { return(NoIntersection); } bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0; if (collinear) { return(ComputeCollinearIntersection(p1, p2, q1, q2)); } /* * At this point we know that there is a single intersection point * (since the lines are not collinear). */ /* * Check if the intersection is an endpoint. If it is, copy the endpoint as * the intersection point. Copying the point rather than computing it * ensures the point has the exact value, which is important for * robustness. It is sufficient to simply check for an endpoint which is on * the other line, since at this point we know that the inputLines must * intersect. */ if (Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) { IsProper = false; /* * Check for two equal endpoints. * This is done explicitly rather than by the orientation tests * below in order to improve robustness. * * [An example where the orientation tests fail to be consistent is * the following (where the true intersection is at the shared endpoint * POINT (19.850257749638203 46.29709338043669) * * LINESTRING ( 19.850257749638203 46.29709338043669, 20.31970698357233 46.76654261437082 ) * and * LINESTRING ( -48.51001596420236 -22.063180333403878, 19.850257749638203 46.29709338043669 ) * * which used to produce the INCORRECT result: (20.31970698357233, 46.76654261437082, NaN) * */ if (p1.Equals2D(q1) || p1.Equals2D(q2)) { IntersectionPoint[0] = p1; } else if (p2.Equals2D(q1) || p2.Equals2D(q2)) { IntersectionPoint[0] = p2; } else if (Pq1 == 0) { IntersectionPoint[0] = q1.Copy(); } else if (Pq2 == 0) { IntersectionPoint[0] = q2.Copy(); } else if (Qp1 == 0) { IntersectionPoint[0] = p1.Copy(); } else if (Qp2 == 0) { IntersectionPoint[0] = p2.Copy(); } } else { IsProper = true; IntersectionPoint[0] = Intersection(p1, p2, q1, q2); } return(PointIntersection); }