Java查找两条直线的交点

4
在Java中,我有一个类Line,它有两个变量:mb,使得该线遵循公式mx + b。我有两条这样的线。如何找到两条线的交点的xy坐标?(假设斜率不同)
这是class Line
import java.awt.Graphics;
import java.awt.Point;

public final class Line {
    public final double m, b;

    public Line(double m, double b) {
        this.m = m;
        this.b = b;
    }

    public Point intersect(Line line) {
        double x = (this.b - line.b) / (this.m - line.m);
        double y = this.m * x + this.b;
        return new Point((int) x, (int) y);
    }

    public void paint(Graphics g, int startx, int endx, int width, int height) {
        startx -= width / 2;
        endx -= width / 2;
        int starty = this.get(startx);
        int endy = this.get(endx);
        Point points = Format.format(new Point(startx, starty), width, height);
        Point pointe = Format.format(new Point(endx, endy), width, height);
        g.drawLine(points.x, points.y, pointe.x, pointe.y);
    }

    public int get(int x) {
        return (int) (this.m * x + this.b);
    }

    public double get(double x) {
        return this.m * x + this.b;
    }
}

1
你已经有了代码:它不起作用吗?另外,想象一下,如果你试图解决两个 y=mx+b 直线,你会在纸上用笔做些什么。将其相等并解出 x,以定义 x 的通解,然后使用任何一个直线公式解出 y。将这些公式转化为代码。 - D. Ben Knoble
你在解决公式方面遇到了困难吗?那就去 [math.se] 吧。还是你在将已知的公式转化为代码时遇到了问题?这应该不难,而且已经有人做过了。 - Teepeemm
4个回答

9

Lets assume you have these 2 functions:

y = m1*x + b1    
y = m2*x + b2

要找到 x轴 的交点,我们可以这样做:
m1*x+b1 = m2*x+b2    
m1*x-m2*x = b2 - b2    
x(m1-m2) = (b2-b1)    
x = (b2-b1) / (m1-m2)

要找到y,您需要使用函数表达式,并将x替换为其值(b2-b1)/(m1-m2)

因此:

y = m1 * [(b2-b1) / (m1-m2)] + b1

你有 (this.b - line.b),改为 (line.b - this.b)

public Point intersect(Line line) {
    double x = (line.b - this.b) / (this.m - line.m);
    double y = this.m * x + this.b;

    return new Point((int) x, (int) y);
}

太好了!我以为只是因为我的数字很小所以出现了一点错误。非常感谢! - user4157653
5
请注意,此解决方案不适用于垂直和平行线。当 m-line.m=0 时,其值未定义。 - Christian

2

@wutzebaer提出的解决方案似乎不起作用,而是尝试下面的解决方案(代码基于以下示例:https://rosettacode.org/wiki/Find_the_intersection_of_two_lines#Java)。 s1和s2是第一条线段的端点,d1和d2是第二条线段的端点。

public static Point2D.Float calculateInterceptionPoint(Point2D.Float s1, Point2D.Float s2, Point2D.Float d1, Point2D.Float d2) {

        double a1 = s2.y - s1.y;
        double b1 = s1.x - s2.x;
        double c1 = a1 * s1.x + b1 * s1.y;

        double a2 = d2.y - d1.y;
        double b2 = d1.x - d2.x;
        double c2 = a2 * d1.x + b2 * d1.y;

        double delta = a1 * b2 - a2 * b1;
        return new Point2D.Float((float) ((b2 * c1 - b1 * c2) / delta), (float) ((a1 * c2 - a2 * c1) / delta));

    }

public static void main(String[] args) {

    System.out.println(calculateInterceptionPoint(new Point2D.Float(3, 5), new Point2D.Float(0, 2), new Point2D.Float(1, 2), new Point2D.Float(4, 0)));

}

是的!这个解决方案可行!点赞!谢谢! - brucemax
对于输入参数,您还可以使用两个 Line2D.Float(字段:x1、y1、x2、y2)。 - Boann

1

这就是我得到的结果。找不到任何不起作用的例外情况:

public static Point calculateInterceptionPoint(Point s1, Point d1, Point s2, Point d2) {

    double sNumerator = s1.y * d1.x + s2.x * d1.y - s1.x * d1.y - s2.y * d1.x;
    double sDenominator = d2.y * d1.x - d2.x * d1.y;

    // parallel ... 0 or infinite points, or one of the vectors is 0|0
    if (sDenominator == 0) {
        return null;
    }

    double s = sNumerator / sDenominator;

    double t;
    if (d1.x != 0) {
        t = (s2.x + s * d2.x - s1.x) / d1.x;
    } else {
        t = (s2.y + s * d2.y - s1.y) / d1.y;
    }

    Point i1 = new Point(s1.x + t * d1.x, s1.y + t * d1.y);

    return i1;

}

public static void main(String[] args) {
    System.out.println(calculateInterceptionPoint(new Point(3, 5), new Point(0, 2), new Point(1, 2), new Point(4, 0)));
    System.out.println(calculateInterceptionPoint(new Point(3, 5), new Point(0, 2), new Point(1, 2), new Point(0, 2)));
    System.out.println(calculateInterceptionPoint(new Point(0, 0), new Point(0, 2), new Point(0, 0), new Point(2, 0)));
    System.out.println(calculateInterceptionPoint(new Point(0, 0), new Point(0, 2), new Point(0, 0), new Point(0, 2)));
    System.out.println(calculateInterceptionPoint(new Point(0, 0), new Point(0, 0), new Point(0, 0), new Point(0, 0)));
}

你不能在构造函数中使用双精度坐标来实例化Point对象;你应该创建一个空对象,然后填充它。构造函数只接受整数值。 - HosseyNJF
1
无论如何,我觉得这个实现有问题。数学似乎不正确。 - TigOldBitties

0

最简单的解决方案:

import java.util.Scanner;
import java.util.Arrays;

public class Main {

  public static void main(String[] args) {
    System.out.println(Arrays.toString(calculateIntersection()));
  }

  public static double[] calculateIntersection() {
    Scanner scanner = new Scanner(System.in);
    System.out.println("The program calculates the point of intersection of two lines, given by their equations: ax + b. Please introduce the a and b coefficients of both lines:");

    double m1 = scanner.nextInt();
    double b1 = scanner.nextInt();
    double m2 = scanner.nextInt();
    double b2 = scanner.nextInt();

    if ((m2 - m1) == 0) {
      throw new ArithmeticException("The lines don't have intersection, because they're parallel.");
    }

    // Intersection [x,y] formula
    double crossX = (b1 - b2) / (m2 - m1);
    double crossY = (m1 * crossX + b1);

    double[] array = new double[] {crossX,crossY};
    return array;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接