将矩阵变换应用于球体

时间:2015-12-11 09:42:54

标签: performance math graphics 3d linear-algebra

我有一个看起来像这样的Sphere结构

if(postion==globalPosition)
{
    //change color like
    textview.setTextColor(Color.RED);
}
else
{
    //revert back to regular color 
    textview.setTextColor(Color.WHITE);
}

如何将4x4变换矩阵应用于该球体?矩阵可能包含比例因子,旋转(显然不会影响球体)和平移。

我正在使用的当前方法包含三个struct Sphere { vec3 _center; float _radius; }; 方法(其中包含length())非常慢。

sqrt()

我想知道是否有人知道更有效的方法来做到这一点?

1 个答案:

答案 0 :(得分:2)

这是关于效率的问题,特别是避免做平方根。一个想法是推迟平方根直到最后一刻。由于长度和长度的平方是从0开始增加的函数,因此比较长度的平方与比较长度相同。因此,您可以避免对length的三次调用并将其设为一次。

#include <glm/gtx/norm.hpp>
#include <algorithm>

glm::vec3 extractScale(const glm::mat4 &m)
{
    // length2 returns length squared i.e. v·v
    // no square root involved
    return glm::vec3(glm::length2( glm::vec3(m[0]) ),
                     glm::length2( glm::vec3(m[1]) ),
                     glm::length2( glm::vec3(m[2]) ));
}

void Sphere::applyTransformation(const glm::mat4 &transformation)
{
    glm::vec4 center = transformation * glm::vec4(_center, 1.0f);
    glm::vec3 scalesSq = extractScale(transformation);
    float const maxScaleSq = std::max_element(&scalesSq[0], &scalesSq[0] + scalesSq.length());  // length gives the dimension here i.e. 3
    // one sqrt when you know the largest of the three
    float const largestScale = std::sqrt(maxScaleSq);

    set(glm::vec3(center), _radius * largestScale);
}

<强>除了: 非均匀刻度意味着沿不同轴的缩放比率不相同。例如。 S 1,2,4 是不均匀的,而S 2,2,2 是均匀的。请参阅this intuitive primer on transformations以更好地了解它们;它有动画来证明这种差异。

规模是否也可以不均匀?从代码看起来它可以。用最大比例变换半径是不对的。如果你是一个非均匀的比例,球体实际上会变成一个椭圆体,因此只是缩放半径是不正确的。您必须将球体转换为具有不同长度的半主轴的ellipsoid