C++、点和线在2D中的位置对舍入误差和位置具有鲁棒性

C++, point and line position in 2D robust to rounding errors and position

本文关键字:位置 鲁棒性 舍入误差 2D C++      更新时间:2023-10-16

直线由两个端点P1[x1,y1],P2[x2,y2]定义。设Q[xq,yq]为测试点。两个坐标都是双坐标。

差异:

dx1 = x2 - x1
dy1 = y2 - y1
dx2 = xq - x1
dy2 = yq - y1

规范

double n1_sq = sqrt(dx1 * dx1 + dy1 * dy1);
double n2_sq = sqrt(dx2 * dx2 + dy2 * dy2);

我的假设:使用归一化向量的测试对舍入误差不太敏感

double test = (dx1 / n1_sq  )  * (dy2 / n2_sq) - ( dx2 / n2_sq ) * ( dy1 / n1_sq );

double test = dx1 * dy2 - dx2 * dy1;

问题出现在以下情况中:

A) 测试点是Q在线上

Q = [0.5(x1 + x2), 0.5(y1 + y2)]

在许多情况下,结果不是零,而是

test >> 0

B) 线路/测试点配置不当

情况1)长段:

让我们将测试点移动到起始点,dist(Q,|p1,p2|)=7e-4

P1 = [0, 0]
P2 = [1000000000.00001, 1000000000.00001]
Q = [0.0,0.001] 

归一化试验:0.7未规范化测试:1.0e+6

情况2)长段:

让我们将测试点移动到终点dist(Q,|p1,p2|)=7e-4

P1 = [0, 0]
P2 = [1000000000.00001, 1000000000.00001]
Q = [1000000000.0, 1000000000.001] 

归一化试验:5.0e-13未规范测试t:1.1 e+6

情况3)短段:

让我们将测试点移动到起始点,dist(Q,|p1,p2|)=7e-4

P1 = [0, 0]
P2 = [0.00001, 0.00001]
Q = [0.0,0.001] 

归一化试验:0.7未规范测试:1.0e-8

结果:

A) 长线段的归一化测试不太可靠。情况2可以被认为是零机械,具有以下决定:Q在|p1,p2|。。。

B) 对于短段,情况相反,未规范化的测试给出机械零。

但两个测试的结果都不是恒定的,并且所得到的值没有带来关于点Q与线|p1,p2|的实际距离的任何信息。在两个测试中都使用阈值并不能得到正确的结果。。。并且阈值的值在之前无法确定。。

我该怎么办?

我的解决方案是用新的测试来代替这两个测试:测试点Q和线P1、p2的距离,并使用一些阈值eps。带的Q点

dist (Q,|P1,P2|) < eps,  (for example 1e-10) 

将被放置在P1、P2线上……测试结果不取决于点的配置(即,如果我们沿着线段P1、P2移动测试点Q)

是否有人使用了更好的测试或对此问题有不同的解决方案?

我不理解你的测试。它似乎根本不涉及Q的坐标。此外,对于两个值uv,以最小舍入来计算范数为M * sqrt(1 + m / M),其中M = max(|u|, |v|)m = min(|u|, |v|)。对于dist函数,这是最好的方法,尽管您可能希望将阈值设为线段长度的函数。这实际上取决于您的应用程序。

使用楔形乘积(在2d中是行列式)来求距离。我想问题是,你可能要减去类似的量,这样你的结果就会被截断误差所克服。请尝试使用点乘。d=d1.d2/|d1|.