繁体   English   中英

如何有效地确定两个平行向量的比例因子?

[英]How do I efficiently determine the scale factor of two parallel vectors?

我有两个三维非零向量,我知道它是平行的,因此我可以将一个向量的每个分量乘以常数以获得另一个。 为了确定这个常数,我可以从两个向量中取出任何字段并将它们相互分开以获得比例因子。

例如:

vec3 vector1(1.0, 1.5, 2.0);
vec3 vector2(2.0, 3.0, 4.0);
float scaleFactor = vector2.x / vector1.x; // = 2.0

不幸的是,每次选择相同的字段(比如x轴)都会使除数为零。

划分矢量的长度是不可能的,因为它不考虑负比例因子。

是否有一种有效的方法可以避免零分割?

所以我们想要一些东西:

1-没有分支

2-避免被零除

3-确保最大可能的分配器

这些要求是通过两个点积的比例来实现的:

(v1 * v2) / (v2 * v2)
= 
(v1.x*v2.x + v1.y*v2.y + v1.z*v2.z) / (v2.x*v2.x + v2.y*v2.y + v2.z*v2.z)

在维度不是(编译时)常量的一般情况下,分子和分母都可以在单个循环中计算。

差不多,这个。

inline float scale_factor(const vec3& v1, const vec3& v2, bool* fail)
{
    *fail = false;
    float eps = 0.000001;
    if (std::fabs(vec1.x) > eps)
        return vec2.x / vec1.x;
    if (std::fabs(vec1.y) > eps)
        return vec2.y / vec1.y;
    if (std::fabs(vec1.z) > eps)
        return vec2.z / vec1.z;

    *fail = true;
    return -1;
}

此外,人们可以考虑获得2个元素的总和,然后通过单个部分获得比例因子。 例如,您可以使用IPP的ippsSum_32f有效地获得总和,因为它是使用SIMD指令计算的。

但是,说实话,我怀疑你能真正改进这些方法。 无论是全部 - >除法还是分支 - >除法将为您提供非常接近最佳的解决方案。

要最小化相对错误,请使用最大元素:

if (abs(v1.x) > abs(v1.y) && abs(v1.x) > abs(v1.z))
    return v2.x / v1.x;
else if (abs(v1.y) > abs(v1.x) && abs(v1.y) > abs(v1.z))
    return v2.y / v1.y;
else
    return v2.z / v1.z;

此代码假定v1不是零向量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM