Java 计算交叉口的数值误差

Java 计算交叉口的数值误差,java,geometry,intersection,numeric,Java,Geometry,Intersection,Numeric,我想计算光线和线段之间的交点。为此,我建立了线性方程,并寻找一个交点。现在我遇到一个数值问题,举个例子。我的代码的缩写: public class Test { public static void main(String[] args) { double rayAX = 443.19661703858895d; double rayAY = 666.3485960845833d; double rayBX = 443.196744279

我想计算光线和线段之间的交点。为此,我建立了线性方程,并寻找一个交点。现在我遇到一个数值问题,举个例子。我的代码的缩写:

public class Test {
    public static void main(String[] args) {
        double rayAX = 443.19661703858895d;
        double rayAY = 666.3485960845833d;

        double rayBX = 443.196744279195d;
        double rayBY = 103.21654864924565d;

        double segAX = 450.0d;
        double segAY = 114.42801992127828d;

        double segBX = 443.196744279195d;
        double segBY = 103.21654864924565d;


        double a1 = (rayBY - rayAY) / (rayBX - rayAX);
        double t1 = rayAY - rayAX * a1;

        double a2 = (segBY - segAY) / (segBX - segAX);
        double t2 = segAY - segAX * a2;

        double x = (t2 - t1) / (a1 - a2);
        double y = a1 * x + t1;

        System.out.println(x);
        System.out.println(y);
    }
}
显然,返回值应该是(443.196744279195103.21654864944565),因为该点在光线和线段上都是相同的。 但实际回报是在我的情况下(443.19674427919506103.2165484284058)

在第二个数字中,小数点后第六位已有错误。
我猜错误是因为rayAX和rayBX的值非常接近。我的问题是:在计算交叉点时,我能得到更精确的结果吗?

这里有一种更稳定的方法来获得交叉点(请注意,它实际上是两条线的交叉点……您的原始代码似乎也没有检查交叉点是否在线段内):


粗略解释:将
A
B
作为射线的端点,将
X
Y
作为线段的端点。让
P
成为我们正在寻找的交点。然后,
PX
PY
的比率等于
ABX
ABY
的面积的比率。您可以使用叉积计算面积,这就是上面的代码所做的。请注意,此过程仅使用一次除法,这有助于将数值不稳定性降至最低。

据我所知,最佳数值稳定性是通过高斯或高斯-乔丹方法和全旋转实现的

您需要求解
R
S
的线性2x2系统

(Brx - Arx).R - (Bsx - Asx).S = Asx - Arx
(Bxy - Ary).R - (Bsx - Asx).S = Asy - Ary
总旋转告诉您选择模块最大的LHS系数。有四种可能的选择,因此您必须实现算法的四个版本

例如,假设左上角系数在系统中占主导地位

A.X + B.Y = C
D.X + E.Y = F
然后

,

使用精确的算法,这确实相当于克拉默法则,但从数值角度看可能更好


其他情况是对称处理的。

当方程组接近时,数值问题总是可能出现的。这肯定更准确!你有一个链接可以让我得到更多关于这个的信息吗?如果我想让两段相交,我想我可以找到另一个t,如果我计算一个新的区域a和一个新的区域B,只需在计算过程中切换“seg”和“ray”?对于这个新的t,我还可以检查它是否在0和1之间。你有任何论文的链接,或者通常描述这种方法的地方吗?还是你自己想出这个方法的?对不起,我没有参考资料。这只是我根据一般的几何知识自己想出来的。不过,这看起来是一个不错的资源:。
A.X + B.Y = C
D.X + E.Y = F
  X + (B/A).Y = (C/A)
D.X + E    .Y = F
(E - D.(B/A)) Y = F - D.(C/A)
Y = (F - D.(C/A)) / (E - D.(B/A))
X = (C/A) - (B/A).Y