给定两个向量u=(ux,uy,uz)
和v=(vx,vy,vz),
,计算最便宜的方法是检查它们是平行还是几乎平行(给定一些阈值来近似),假设向量没有标准化?
关于几乎平行:例如,我们假设一个阈值直到第一个小数部分,例如,如果它们的叉积是0.01
,我们可以安全地假设它们是平行的。我们可以类似地放宽我们可能想要使用的其他方法的条件。
如果首选遵循编程语言来回答,让我们假设我们想在c ++中这样做。
简短回答:从理论上讲,它根本不重要。实际上:衡量它
答案很长:
同意逆三角函数是不可能的,让我们比较计算最后两个选项的最有效方法。
由于允许矢量几乎平行,因此需要计算
crossx := uy * vz + uz * vy;
crossy := ...;
crossz := ...;
crossNorm = crossx * crossx + crossy * crossy + crossz * crossz;
其中涉及9次乘法和5次加法。如果向量(几乎)平行,那么crossNorm
应该(几乎)为零。
然而,正如Baum mit Augen正确指出的那样,检查crossx
,crossy
和crossz
几乎为零就足够了,将其减少到6次乘法和3次加法,最多可以进行两次比较。哪个更有效,取决于您的语言的细节和“几乎”相等的定义 - 例如如果接近等于意味着fabs(...) < 1E-6
它可能只值得做一次。
标量产品是
scalar = ux * vx + uy * vy + uz * vz;
如果矢量(几乎)平行则
scalar * scalar
应该(几乎)相等
(ux * ux + uy * uy + uz * uz) * (vx * vx + vy * vy + vz * vz).
这归结为10次乘法和6次加法。
这只是上面的计算,但有两个额外的double
分区。这不会增加任何价值,事实上它可能只会引入舍入问题。
两个选项的双重操作数几乎相同。如果你真的想知道,你可以比较组件https://godbolt.org/z/nJ9CXl,但差异对于所有实际目的来说都是最小的。事实上,如果你只计算“昂贵的”指令(mulsd
,addsd
,subsd
)和比较(ucomisd
)两个选项都有五个。但是,如果你必须确切知道,请测量它!
我认为这是错误的
标量= l1 * l2 * cos(r)= ux * vx + uy * vy + uz * vz标量^ 2 =(l1 * l2 * cos(r))^ 2 =(ux * vx + uy * vy + uz * vz)^ 2
(l1 * l2)^ 2 =(ux * ux + uy * uy + uz * uz)*(vx * vx + vy * vy + vz * vz)所以cos(x)^ 2 =标量^ 2 /(ux * ux + uy * uy + uz * uz)*(vx * vx + vy * vy + vz * vz)=(ux * vx + uy * vy + uz * vz)^ 2 /(ux * ux + uy * uy + uz * uz)*(vx * vx + vy * vy + vz * vz)
当cos为1或-1时,x接近0或180,因此cos(x)^ 2 - > 1
当这个
公式接近1
(他们*在+哦*你+从*雷克斯)^ 2 /(他们*他们+哦*哦+出*出)*(在re * in re + you * you + ref * re)那个boyswire westre paraliel