如何沿任意轴缩放对象(在3D空间中)

时间:2013-08-11 21:40:13

标签: c++ opengl matrix scale

我正在尝试使用opengl在c ++中编写一个物理模拟器,我需要能够沿着相机所面对的轴缩放对象(现在大多数是立方体)。

我可以使用它作为我的模型矩阵完美地绘制对象:

mat4 Model = Translate(cube.Position - float3(gl.Position.x, gl.Position.y, -gl.Position.z)) * Rotate(cube.Rotation) * Scale(cube.Scale);

gl.Position是cam的位置,float3是像我写的那样的vec3等等......

所以我尝试修改该行以在所有其他内容之前包含缩放因子(最后应用最终的内容):

mat4 Model = Translate(cube.Position - float3(gl.Position.x, gl.Position.y, -gl.Position.z)) * Rotate(cube.Rotation) * Scale(cube.Scale) * (Rotate(float3(gl.Rotation.x, gl.Rotation.y, gl.Rotation.z)) * Scale(float3(1.0f, 1.0f, sqrt(1 - (velocity * velocity)))) * Rotate(float3(tau - gl.Rotation.x, tau - gl.Rotation.y, tau - gl.Rotation.z)));

这是最重要的部分,我旋转对象,缩放它,然后将其旋转回来.. sqrt(1 - (速度*速度))是物理部分(Lorentz收缩)和gl.Rotation是一个vec3,其中每个轴以凸轮的弧度保持俯仰,偏航和滚动。我的翻译,旋转等功能正常工作,但我需要帮助创建一个可扩展的矩阵的理论。

2 个答案:

答案 0 :(得分:1)

缩放矩阵的形式如下:

{{s_x, 0, 0, 0},
 {0, s_y, 0, 0},
 {0, 0, s_z, 0},
 {0,  0,  0, 1}}

假设坐标一致。

要应用它们,您需要缩放,然后旋转,然后翻译。我建议使用gl函数来执行此操作。假设您希望对象位于x,y,z位置,并且其旋转位于四元数{theta,r_x,r_y,r_z}中。缩放和旋转需要在模型坐标系中进行。 GL以适当的顺序应用转换,因此其代码如下所示:

glTranslatef(x, y, z);
glRotatef(theta, r_x, r_y, r_z);
glScalef(s_x, s_y, s_z);

//draw my model

答案 1 :(得分:1)

我通过编写基于pippin1289解决方案的这个函数来解决它

mat4 ScaleOnAxis(float3 a)
{
    a = Norm3f(a);

    if(a == x || (a.x == -1.0f && a.y == 0.0f && a.z == 0.0f))
        return Scale(0.2f, 1.0f, 1.0f);

    float3 axis = Cross(a, x);
    float theta = acos(Dot(a, x));

    if(theta > pi / 2)
    {
        axis = axis * -1.0f;
        theta = pi - theta;
    }

    Quaternion ToRotation(axis.x, axis.y, axis.z, theta);
    Quaternion FromRotation(axis.x, axis.y, axis.z, tau - theta);

    return mat4(FromRotation) * (Scale(float3(0.2f, 1.0f, 1.0f)) * mat4(ToRotation));
}

它返回一个矩阵,在轴上缩放0.2