计算几何之求两条线段的交点

这个图是从知乎上保存下来的:

其实主要是利用了三角形的相似:

代码如下:

// 两点式直线公式:(x - x1) / (x2 - x1) = (y - y1) / (y2 - y1)
// --> x(y2 - y1) + y(x1 - x2) + x1(y1 - y2) + y1(x2 - x1) = 0
// A = y2-y1, B = x1-x2, C = x1(y1 - y2) + y1(x2 - x1)
// (x,y) = d2/(d1+d2) * (x3,y3) + d1/(d1+d2) * (x4,y4)
// d2/(d1+d2) = |A*x4 + B*y4 + C|/(|A*x4 + B*y4 + C|+|A*x3 + B*y3 + C|)
// d1/(d1+d2) = |A*x3 + B*y3 + C|/(|A*x4 + B*y4 + C|+|A*x3 + B*y3 + C|)
public static Point detectIntersection(Point a, Point b, Point c, Point d) {

    // whether intersect ?
    boolean intersect = (PointPosition.isLeft(a, b, c) ^ PointPosition.isLeft(a, b, d)) && (PointPosition.isLeft(c, d, a) ^ PointPosition.isLeft(c, d, b));
    if (!intersect) return null;

    double d2 = Math.abs((b.y - a.y) * d.x + (a.x - b.x) * d.y + a.x * (a.y - b.y) + a.y * (b.x - a.x));
    double d1 = Math.abs((b.y - a.y) * c.x + (a.x - b.x) * c.y + a.x * (a.y - b.y) + a.y * (b.x - a.x));
    double x = d2 / (d1 + d2) * c.x + d1 / (d1 + d2) * d.x;
    double y = d2 / (d1 + d2) * c.y + d1 / (d1 + d2) * d.y;
    return new Point(x, y);
}

要注意一点的是:这里会检测是否相交了,因此这里要坐下左检测:

/**
 * ->
 * a:(x1, y1), point A:(x2, y2)
 */
private static boolean isLeft(double x1, double y1, double x2, double y2) {
    // a'=(-y1, x1) or (y1, -x1), return a' x A = (-y1, x1) x (x2, y2)
    return (-y1 * x2 + x1 * y2) > 0;
}

/**
 * ->
 * pq and point s
 */
public static boolean isLeft(Point p, Point q, Point s) {
    return isLeft(q.x - p.x, q.y - p.y, s.x - p.x, s.y - p.y);
}
发布了29 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/u012803274/article/details/99450143