Line Segments Intersection(intersection Point)

删除回忆录丶 提交于 2020-01-17 02:57:30

问题


I have created a function to calculate the intersection point of two line segment .

Unfortunantly the code below dosen't work if one of the segment is verticale

    public static Point intersection(Segment s1, Segment s2) {
    double x1 = s1.getP1().getX();
    double y1 = s1.getP1().getY() ;
    double x2 = s1.getP2().getX();
    double y2 = s1.getP2().getY() ;
    double x3 = s2.getP1().getX();
    double y3 = s2.getP1().getY();
    double x4 = s2.getP2().getX();
    double y4 = s2.getP2().getY();

    double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
    if (d == 0) {
        return null;
    }
    double xi = ((x3 - x4) * (x1 * y2 - y1 * x2) - (x1 - x2) * (x3 * y4 - y3 * x4)) / d;
    double yi = ((y3 - y4) * (x1 * y2 - y1 * x2) - (y1 - y2) * (x3 * y4 - y3 * x4)) / d;
    Point p = new Point(xi, yi);
    if (xi < Math.min(x1, x2) || xi > Math.max(x1, x2)) {
        return null;
    }
    if (xi < Math.min(x3, x4) || xi > Math.max(x3, x4)) {
        return null;
    }
    return p;
}

the problem when i have a vertical line segment , this formula

double d = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);

is equal to 0 and the method return null.

How can I handle this exception.

Thank you


回答1:


Line intersection without special cases

Coming from a background of projective geometry, I'd write the points in homogeneous coordinates:

v1 = [x1, y1, 1]
v2 = [x2, y2, 1]
v3 = [x3, y3, 1]
v4 = [x4, y4, 1]

Then both the line joining two points and the intersection of two lines can be expressed using the cross product:

[x5, y5, z5] = (v1 × v2) × (v3 × v4)

which you can dehomogenize to find the resulting point as

[x5/z5, y5/z5]

without having to deal with any special cases. If your lines are parallel, the last point would lead to a division by zero, though, so you might want to catch that case.

Restriction to segments

The above is for infinite lines, though. You might want to keep the code which returns null if the point of intersection falls outside the bounding box. But if you want real segments, that code is incorrect: you could have a point of intersection which lies outside one of the segments but still inside the bounding box.

A proper check can be implemented using an orientation-checking predicate. The determinant of three of the vectors vi given above will have positive sign if the triangle they form has one orientation, and negative sign for the opposite orientation. So the points v3 and v4 lie on different sides of s1 if

det(v1, v2, v3) * det(v1, v2, v4) < 0

and in a similar way v1 and v2 lie on different sides of s2 if

det(v3, v4, v1) * det(v3, v4, v2) < 0

so if both of these are satisfied, you have an intersection between the segments. If you want to include the segment endpoints, change the < to a in these inequalities.




回答2:


I have tried code it without testing... I hope it works! ^^

public static Point intersection(Segment s1, Segment s2) {
    // Components of the first segment's rect.
    Point v1 = new Point(s1.p2.x - s1.p1.x, s1.p2.y - s1.p1.y); // Directional vector
    double a1 = v.y;
    double b1 = -v.x;
    double c1 = v1.x * s1.p1.y - s1.v.y * s1.p1.x;

    // Components of the second segment's rect.
    Point v2 = new Point(s2.p2.x - s2.p1.x, s2.p2.y - s2.p1.y);
    double a2 = v2.y;
    double b2 = -v2.x;
    double c2 = v2.x * s2.p1.y - s2.v.y * s2.p1.x;

    // Calc intersection between RECTS.
    Point intersection = null;
    double det = a1 * b2 - b1 * a2;
    if (det != 0) {
        intersection = new Point(
            (b2 * (-c1) - b1 * (-c2)) / det;
            (a1 * (-c2) - a2 * (-c1)) / det;
        );
    }

    // Checks ff segments collides.
    if (
        intersection != null &&
        (
            (s1.p1.x <= intersection.x && intersection.x <= s1.p2.x) ||
            (s1.p2.x <= intersection.x && intersection.x <= s1.p1.x)
        ) &&
        (
            (s1.p1.y <= intersection.y && intersection.y <= s1.p2.y) ||
            (s1.p2.y <= intersection.y && intersection.y <= s1.p1.y)
        ) &&
        (
            (s2.p1.x <= intersection.x && intersection.x <= s2.p2.x) ||
            (s2.p2.x <= intersection.x && intersection.x <= s2.p1.x)
        ) &&
        (
            (s2.p1.y <= intersection.y && intersection.y <= s2.p2.y) ||
            (s2.p2.y <= intersection.y && intersection.y <= s2.p1.y)
        )
    )
        return intersection;

    return null;
};


来源:https://stackoverflow.com/questions/29854085/line-segments-intersectionintersection-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!