检查两个向量是否并行的最有效方法
Most efficient way to check if two vectors are parallel
给定两个向量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 =scalar^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
(UX * VX + UY * vy + uz * vz(^2/(UX * UX + uy * uy + uz * uz( * (vx * vx + vy * vy + vz * vz( 这意味着向量是平行的
- 欧拉项目#8答案是大以获得有效答案
- 调整大小后指向元素值的指针unordered_map有效?
- 为什么是0;C++中的有效语句
- 最高有效数字侧的第N位
- GCC对可能有效的代码抛出init list生存期警告
- 有效地使用std::unordered_map来插入或增加键的值
- C++17中的并行执行策略
- c++中O(n^(1/3))中一个数的除数的有效计数
- 使用无符号字符数组有效存储内存
- 自定义先决条件对移动分配运算符有效吗
- 并行用于C++17中数组索引范围内的循环
- 如何在Elixir中调用递归函数并行
- OpenMP:并行更新数组总是需要减少数组吗
- 如何使用OpenMP并行这两个循环
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 我们如何并行运行算法的 n 个实例并以有效的方式计算结果函数的平均值?
- 检查两个向量是否并行的最有效方法
- 算法找到最有效的并行发送数据的方式
- 如何有效地并行化分治算法