private static int intersect2D2Segments(final Point s1p0, final Point s1p1, final Point s2p0, final Point s2p1) {
        final long ux = s1p1.x - s1p0.x; // vector u = S1P1-S1P0 (segment 1)
        final long uy = s1p1.y - s1p0.y;
        final long vx = s2p1.x - s2p0.x; // vector v = S2P1-S2P0 (segment 2)
        final long vy = s2p1.y - s2p0.y;
        final long wx = s1p0.x - s2p0.x; // vector w = S1P0-S2P0 (from start of segment 2 to start of segment 1
        final long wy = s1p0.y - s2p0.y;

        final double d = ux * vy - uy * vx;

        // test if  they are parallel (includes either being a point)
        if (d == 0) {           // S1 and S2 are parallel
            if ((ux * wy - uy * wx) != 0 || (vx * wy - vy * wx) != 0) {
                return 0; // they are NOT collinear
            }

            // they are collinear or degenerate
            // check if they are degenerate  points
            final boolean du = (ux == 0) && (uy == 0);
            final boolean dv = (vx == 0) && (vy == 0);
            if (du && dv) {            // both segments are points
                return (wx == 0 && wy == 0) ? 0 : 1; // return 0 if they are distinct points
            }
            if (du) {                     // S1 is a single point
                return inSegment(s1p0, s2p0, s2p1) ? 1 : 0; // is it part of S2?
            }
            if (dv) {                    // S2 a single point
                return inSegment(s2p0, s1p0, s1p1) ? 1 : 0;  // is it part of S1?
            }
            // they are collinear segments - get  overlap (or not)
            double t0;                    // endpoints of S1 in eqn for S2
            double t1;
            final int w2x = s1p1.x - s2p0.x; // vector w2 = S1P1-S2P0 (from start of segment 2 to end of segment 1)
            final int w2y = s1p1.y - s2p0.y;
            if (vx != 0) {
                t0 = wx / vx;
                t1 = w2x / vx;
            } else {
                t0 = wy / vy;
                t1 = w2y / vy;
            }
            if (t0 > t1) {                   // must have t0 smaller than t1
                final double t = t0;     // swap if not
                t0 = t1;
                t1 = t;
            }
            if (t0 > 1 || t1 < 0) {
                return 0;      // NO overlap
            }
            t0 = t0 < 0 ? 0 : t0;               // clip to min 0
            t1 = t1 > 1 ? 1 : t1;               // clip to max 1

            return (t0 == t1) ? 1 : 2;        // return 1 if intersect is a point
        }

        // the segments are skew and may intersect in a point
        // get the intersect parameter for S1

        final double sI = (vx * wy - vy * wx) / d;
        if (sI < 0 || sI > 1) {              // no intersect with S1
            return 0;
        }

        // get the intersect parameter for S2
        final double tI = (ux * wy - uy * wx) / d;
        return (tI < 0 || tI > 1) ? 0 : 1; // return 0 if no intersect with S2
    }
intersect2D_2Segments(): find the 2D intersection of 2 finite segments

@param s1p0 start point of segment 1
@param s1p1 end point of segment 1
@param s2p0 start point of segment 2
@param s2p1 end point of segment 2
@return 0=disjoint (no intersect)
1=intersect in unique point I0
2=overlap in segment from I0 to I1
main/src/main/java/cgeo/geocaching/brouter/core/OsmNogoPolygon.java