java-数值不精确计算交集

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

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.196744279195,103.21654864924565),因为射线和线段上的这一点相同.
但实际回报率以我为例(443.19674427919506,103.21654844284058)

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

解决方法:

这是一种在数值上更稳定的相交方式(请注意,它实际上是两条线的相交……似乎您的原始代码也没有检查相交是否也在线段内):

double rX = rayBX - rayAX;                                                                                                                                           
double rY = rayBY - rayAY;                                                                                                                                           

double sAX = segAX - rayAX;                                                                                                                                          
double sAY = segAY - rayAY;                                                                                                                                          
double areaA = sAX * rY - sAY * rX;                                                                                                                                  

double sBX = segBX - rayAX;                                                                                                                                          
double sBY = segBY - rayAY;                                                                                                                                          
double areaB = sBX * rY - sBY * rX;                                                                                                                                  

double t = areaA / (areaA - areaB);
// if t is not between 0 and 1, intersection is not in segment                                                                                                 
double x = (1 - t) * segAX + t * segBX;                                                                                                                              
double y = (1 - t) * segAY + t * segBY;

粗略的解释:假设A和B为射线的端点,让X和Y为线段的端点.令P为我们要寻找的交点.然后,PX与PY之比等于ABX面积与ABY面积之比.您可以使用叉积计算面积,即上面的代码正在执行的操作.请注意,此过程如何仅使用一个除法,这有助于最小化数值的不稳定性.

上一篇:WEB入门 bugku web5


下一篇:R list和data frame 排序