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