Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 试图找出两条线段是否相交_Java_Algorithm_Line Segment - Fatal编程技术网

Java 试图找出两条线段是否相交

Java 试图找出两条线段是否相交,java,algorithm,line-segment,Java,Algorithm,Line Segment,我有一条由两点p1和p2组成的线段,还有一条由点p3和p4组成的第二条线段。我正试图弄清楚它们是否相交,到目前为止,我还没有运气。这是我目前的代码: public static double angle(Point p1, Point p2, Point p3) { double AB = length(p2, p1); double BC = length(p2, p3); double AC = length(p3, p1); return Math.acos

我有一条由两点p1和p2组成的线段,还有一条由点p3和p4组成的第二条线段。我正试图弄清楚它们是否相交,到目前为止,我还没有运气。这是我目前的代码:

public static double angle(Point p1, Point p2, Point p3) {
    double AB = length(p2, p1);
    double BC = length(p2, p3);
    double AC = length(p3, p1);
    return Math.acos((sqr(BC) + sqr(AB) - sqr(AC)) / (2 * BC * AB)) * (180 / Math.PI);
}

public static boolean doIntersect(Point p1, Point p2, Point p3, Point p4) {
    double a = angle(p4, p3, p2);
    double b = angle(p3, p2, p1);
    double c = 180 - b - a;

    System.out.println("a: " + a + ", b: " + b + ", c:" + c);

    if((length(p3, p2) * Math.sin(a)) / Math.sin(c) > length(p2, p1)) return false;
    if((length(p3, p2) * Math.sin(b)) / Math.sin(c) > length(p3, p4)) return false;
    return true;
}

public static double length(Point point1, Point point2) {
    return Math.sqrt(sqr(point1.x - point2.x) + sqr(point1.y - point2.y));
}

public static double sqr(double doub) {
    return Math.pow(doub, 2);
}
但这不起作用。有时,角度“c”甚至是负数


此外,Point是一个具有两个参数的自定义类:x和y。应该是不言自明的。

我建议先提出一个数学解决方案,验证它,然后尝试将它迁移到计算机程序中。

有两种解决方案,每种都有各自的优点:

一,。数学解

从两个点p1和p2,可以很容易地推导出穿过这两个点的线的公式
y=m*x+b
。对于由(p1,p2)和(p3,p4)定义的线的公式,通过均衡计算它们的交点也很容易。剩下要做的就是检查交点是否是两条线段的一部分,这一点非常明显

二,。算法解

另一种方法是应用:根据各自的x坐标对所有点进行排序。然后,对于x顺序中的每个点,想象一条从一点跳到另一点的垂直线

如果在访问了线段A中的所有点后,从线段B到达第一个点,则不存在交点

否则,第一点来自线段A,第二点来自线段B。因此,第三点和第四点分别属于A和B或B和A。将注意力集中在y坐标上,并自行解决此解决方案的最后一部分。;-)


编辑:或者更简单一些,请访问Wikipedia。

对于角度计算,不要使用复杂的方法,将x和y差的平方相加,然后取和的平方根,然后将该值平方,然后使用
acos
,可以使用它从x和y差计算出适当象限中的角度。这比
acos
方法更快,问题更少

然而,根本不需要计算任何角度。相反,如果重叠不可行,则首先进行测试。也就是说,如果
(x),则返回
No
₁≤x₃≤x₂ || x₁≤x₄≤x₂ || x₃≤x₁≤x₄ || x₃≤x₂≤x₄) && (y)≤Y₃≤Y₂ || Y₁≤Y₄≤Y₂ || Y₃≤Y₁≤Y₄ || Y₃≤Y₂≤Y₄))为false。(让p₁,P₂ 是一个线段的端点,p₃,P₄ 另一个的端点。)

如果该情况不可行,则可以通过查看三角形区域的符号是否为p来测试是否发生相交₁,P₂,P₃ 和p₁,P₂,P₄ 是不同的。p的面积₁,P₂,P₃ 是±(x₁·Y₂-x₂·Y₁ + x₃·(y)₂-Y₁) + Y₃·(十)₂-x₁))/2,1/2的因子可以忽略,因为它不影响符号。也就是说,对于可行的情况,您可以计算
t=x₁·Y₂-x₂·Y₁
u=t+x₃·(y)₂-Y₁) + Y₃·(十)₂-x₁)
v=t+x₄·(y)₂-Y₁) + Y₄·(十)₂-x₁)

如果
u·v,则返回
Yes
≤ 0
,else
No
。使用这种方法的目的是避免检查垂直线或水平线、平行线或重合线等产生的所有特殊情况。如果预计会出现退化线,则报告
Yes
如果
u·v<0
,或
No
如果
u·v>0
,否则进行测试如果一条直线在另一条直线上有一个端点。

你能试着解释一下你的数学吗?你可能想检查一下嗨,对不起,我想这是个好主意。基本上,我用四个点做一个伪三角形,然后解出所有的角度(这就是前三条直线).然后,我就这样解三角形:然后计算直线是否比解出的三角形的直线短(意思是它们不相交)对不起,如果这是一个有点奇怪的方法,我自己想出来的。你可能想用这个,然后解两个方程组,找到交点。然后它就像检查两条线是否都包含那个点一样简单。我想这可能正是我在做的,至少是你解释的方式。我在计算通过解三角形(在我给你的链接中,交点是C,A是p1,B是p3)来确定交点的位置然后计算线段是否足够长以到达它。由于某种原因,它不起作用,我认为我的实现在某个地方出了问题。好吧,他必须把他的想法写进代码中,然后在这里发布。这个问题甚至可以放在Math SE,或者cstheory上