我有一个看起来像这样的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()
我想知道是否有人知道更有效的方法来做到这一点?
答案 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。