检查两个顶点是否相等是否正确且一致?

问题描述 投票:0回答:1

我正在编写一个 Typescript 游戏,其中有绘制到画布上的顶点,以及来自它们的一些边。我想确定来自不同顶点的某些边是否相交。为此,我使用通用

doLinesIntersect
函数来确定两条边是否相交。

但是,问题是它显示所有线相交,因为如果两条边共享一个顶点,它们计算为始终相交,但我不希望这样。我可以通过手动检查它们是否共享一个顶点来使其“工作”,如下所示:

function doLinesTrulyIntersect(aX1: number, aY1: number, aX2: number, aY2: number, bX1: number, bY1: number, bX2: number, bY2: number): boolean {
  const sharesVertexes = (aX1 === bX1 && aY1 === bY1) || 
                         (aX1 === bX2 && aY1 === bY2) || 
                         (aX2 === bX1 && aY2 === bY1) || 
                         (aX2 === bX2 && aY2 === bY2);

  return !sharesVertexes && doLinesIntersect(
    aX1, aY1, aX2, aY2,
    bX1, bY1, bX2, bY2
  );
}

基本上,如果两条边共享一个顶点,那么它们不会相交。

但是,这总是有效吗?逻辑是,既然如果两条边具有相同的顶点,那么(因为它们是同一个点),浮点相等测试应该起作用,对吗?毕竟,它们的底层是完全相同的。

但是,我知道通常测试两个浮点是否相等是不正确且不一致的,但这适用于这种情况吗?

typescript floating-point geometry line precision
1个回答
0
投票

如果一条边上的端点X和另一条边上的端点Y设置为等于同一点P,则X等于Y。浮点实体不是自发变化的神秘实体,相等性测试报告两个事物相等当且仅当它们相等时。

当您看到有关比较浮点数是否相等的警告时,实际问题是比较任何类型的近似值,而不是浮点算术所特有的任何内容。假设有一些理想数 N 并且我们有两个近似值 ABNAB 相等吗?很可能不是,因为以不同的方式准备两个近似值通常会产生不同的结果。要估计美国蓝眼睛人口的百分比,您可能会出去对 1,000 人进行抽样,并得出一些百分比 A,另一个人可能会出去对其他 1,000 人进行抽样,并得出一些百分比 B 。尽管这两者都是 N 的近似值,但它们很可能不相等。

在浮点运算中出现这个问题的原因是,浮点主要是为“近似”实数运算而设计的,并且主要用于此目的。请注意,它是浮点算术,近似于实数算术。浮点数字是实际的实数(它们的子集)。这些数字没有任何近似或其他奇怪的地方:每个浮点数都是一个实数。当您将浮点变量设置为浮点数时,它会保留该数字。它不会改变或变得近似。 浮点数的计算过程会引入近似值和舍入误差:大多数浮点运算,包括加法和其他算术、科学函数,以及从十进制转换为浮点格式(包括源代码中的十进制数字)代码或程序输入)是可能对其结果进行四舍五入以适合浮点格式的操作。

请注意,上述内容实际上适用于

任何

数字格式。当精确的数学结果不符合格式时,定点数的计算也会产生舍入结果。并且整数的计算也被调整以适应整数格式。整数算术中的 7/3 产生 2,误差大于 10 分之一,而“双精度”浮点中的

7./3.
误差小于千万亿分之一。因此,整数运算的舍入误差可能比浮点运算严重得多。人们之所以对浮点舍入而不是整数舍入持谨慎态度,是因为我们使用这些格式的主要方式,而不是因为它们固有的对错误的敏感性。
此外,一旦您使用近似值,所有结果都是近似值。通过减去两个几乎相等的数字,您可以获得非常大的相对误差。人们对比较提出警告,因为这是新手可能误用的一种操作。但是,每当您使用任何格式的近似值时,您都应该了解可能发生的错误以及错误的大小。

以上所有内容都是为了给您提供背景信息,以确定您可以依赖哪些操作。如果您将两个端点设置为同一点并稍后比较它们,它们将比较为相等。

您描述的问题中可能出错的一些事情是:

您一开始就没有将两个端点设置为同一点。
  • 某些东西会改变一个或两个端点的值。
  • 计算的内容与端点之间进行比较,而不是直接在两个端点之间进行比较。例如,如果我们有一条边 XY 和一条边 YZ 具有公共端点 Y,并且某些软件计算它们相交的位置,那么这些计算可能会产生与 Y 略有不同的点 Y'。
© www.soinside.com 2019 - 2024. All rights reserved.