这是关于精确执行以下比较:
CrossProduct(P - P0, P1 - P0) >, < or == 0
问题定义
给定由以下等式描述的一组网格点
P(x, y) = P(i, j) * delta = P(i * delta, j * delta)
其中0 <= i&lt;分辨率,0&lt; = j&lt;分辨率,delta = size /(resolution -1)
给定任意3个不同点P0,P1和P2的组合,需要为表达式获得准确的布尔值:
CrossProduct(P1 - P0, P2 - P0) < 0
CrossProduct(P1 - P0, P2 - P0) > 0
CrossProduct(P1 - P0, P2 - P0) == 0
哪里
CrossProduct(lhs, rhs) = lhs.x * rhs.y - lhs.y * rhs.x
整数解决方案
如果我们使用整数来描述点,只要没有溢出就可以使用整数数学来精确计算这些表达式。
P = (i, j)
由于i和j都是&gt; = 0,| i1 - i0 | &LT;因此,CrossProduct将始终具有两个坐标不大于分辨率的参数。所以,没有溢出:
a * b - c * d <= int.MaxValue
其中| a |,| b |,| c |,| d | &LT;分辨率
为无溢出提供以下最大分辨率:
maxResolution * maxResolution + maxResolution * maxResolution <= int.MaxValue
2 * maxResolution² <= int.MaxValue
maxResolution <= (int.MaxValue / 2)^(1/2)
For integers : maxResolution = 2^15 + 1
For longs : maxResolution = 2^31 + 1
使用整数可以完美地工作。唯一的缺点是,点被存储为整数P(i,j),并且每次需要访问实际点值时,需要使用初始公式来获得该点的浮点值P(x) ,y)
问题
是否可以使用浮点数而不是整数来实现此目的?怎么样?
答案 0 :(得分:0)
这是可能的,但并不容易。本文讨论计算几何的谓词 https://www.cs.cmu.edu/~quake/robust.html
但是如果某些几何任务需要它,你可以描述它。例如,如果我们想对多边形进行布尔运算,我们不需要对线交点和方向进行精确正确的求解。我们只需要使用谓词的可重复性。它可以更容易地完成马赫。
答案 1 :(得分:0)
浮动存储mantissas有24位有效位。这意味着您的点集中最大坐标上的相对误差至少为2 ^ -24。
因此,除非您的问题具有不均匀的结构(接近原点的点密度更大),否则将所有坐标重新调整为[-2 ^ 24,2 ^ 24] x [-2 ^ 24, 2 ^ 24]域,并截断为整数,永远忘记浮点数。甚至还有7个备用位的准确度,您可以映射到[-2 ^ 31,2 ^ 31] x [-2 ^ 31,2 ^ 31],这远远超出您的需要。
这样做,用64位整数计算带符号区域就完全没有溢出。
你可能不愿意牺牲小坐标的一些重要部分,但在实际情况下这应该不重要。
如果坐标是双坐标,则有2 ^ 53个尾数位,其中很大一部分必须是噪声。然后检查有效位的实际数量是有意义的。你会发现你有足够的......花车。