你如何规范零矢量

the*_*rty 26 language-agnostic math vector

假设你有一个函数'normalize',它将一个数字列表(代表一个向量)作为输入,并返回规范化的向量.当向量全为零或其分量之和为零时,结果应该是什么?

Yuv*_*dam 33

从数学上讲,零矢量无法归一化.它的长度将始终保持不变0.

对于给定的向量,v = (v1, v2, ..., vn)我们有:||v|| = sqrt(v1^2 + v2^2 + ... + vn^2).让我们记住,规范化的向量是具有的||v||=1.

所以v = 0我们有:||0|| = sqrt(0^2 + 0^2 + ... + 0^2) = 0.你永远无法规范化.

同样重要的是要注意,为确保一致性,您不应返回NaN任何其他空值.v=0确实是标准化的形式v=0.

  • 我认为一个小但重要的改进是要提到它无法标准化的实际原因是因为最终需要尝试除以正在标准化的向量的零长度,这就是部分这实际上是不可能/定义的。尽管如此,+1 (2认同)
  • “v=0 的标准化形式确实是 v=0。” 这是没有意义的:正如您自己所说,零向量无法标准化。 (2认同)

sim*_*mon 12

它比尤瓦尔建议的更糟糕.

在数学上,给定一个向量x,你正在寻找一个新的向量x/|| x ||

其中||.|| 是常态,你可能会认为它是欧几里德规范

||.|| = sqrt(dot(v,v))= sqrt(sum_i x_i**2)

这些是浮点数,因此仅仅防止除以零是不够的,如果x_i都很小(它们可能下溢并且你失去幅度),你也会有一个浮点问题.

基本上它归结为如果你真的需要能够正确处理小向量,你将不得不做更多的工作.

如果小应用程序和零向量在您的应用程序中没有意义,则可以测试向量的大小并执行适当的操作.

(请注意,一旦开始处理浮点数,而不是真实的数字,做平方然后平方根数(或它们的总和)之类的事情在可表示范围的大小两端都是有问题的)

底线:在所有情况下正确地进行数值工作比最初看起来更棘手.

例如,以天真的方式完成此(规范化)操作的潜在问题

  • 所有组件(x_i)都太小了
  • 任何单个组件太大(高于最大可表示的平方根)将返回无穷大.这会按sqrt分割可用的大小.
  • 如果大部件与小部件的比例太大,如果不小心,可以有效地丢失小部件的方向
  • 等等


lib*_*ako 5

从数学上讲,零矢量无法归一化.这是我们在计算几何中称之为"退化情况"的一个例子,这是一个很大的话题,让几何算法设计者感到非常头疼.我可以想象以下解决问题的方法.

  1. 你没有对零矢量情况做任何特别的事情.如果矢量类型具有浮点类型坐标,则结果中将得到零或无限坐标(由于除以零).
  2. 你扔了一个degenerate_case_exception.
  3. 您为过程引入了一个布尔is_degenerate_case输出参数.

我个人在我的代码中到处使用3方法.它的一个优点是它不会让程序员忘记处理退化的情况.

注意,由于浮点数的范围有限,即使输入向量不等于零向量,您仍可能在输出向量中获得无限坐标.因此,我不认为1.方法是一个糟糕的设计决策.

我可以推荐你是为了避免异常抛出解决方案.如果退化情况在其他情况中很少见,那么异常抛出不会减慢程序的速度.但问题在于,在大多数情况下,你不可能知道堕落的病例很少见.