【问题标题】:How To Scale Object Along Any Axis (In 3D Space)如何沿任意轴缩放对象(在 3D 空间中)
【发布时间】:2013-08-13 04:10:21
【问题描述】:

我正在尝试使用 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 是凸轮的位置,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 - (velocity * velocity)) 是物理部分(洛伦兹收缩),而 gl.Rotation 是一个 vec3,其中每个轴以凸轮的弧度保持俯仰、偏航和滚动。我的平移、旋转等功能可以正常工作,但我需要有关创建矩阵以进行缩放的理论方面的帮助。

【问题讨论】:

标签: c++ opengl matrix scale


【解决方案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 缩放的矩阵

【讨论】:

    【解决方案2】:

    缩放矩阵的形式为:

    {{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
    

    【讨论】:

    • 也许你没有理解我的问题,看到比例矩阵只会在 x、y 和 z 轴上独立缩放,(例如,将立方体变成矩形棱柱)但它将无法沿 (0.5, 0, 0.5) 的向量缩放创建 3d 平行四边形(这是我需要的)
    • 为什么 glScale(0.5, 0, 0.5) 不会产生你想要的效果?或为您需要的任何缩放幅度提供 0.5。
    • 因为 glScale 会将它的长度减半,高度为零,宽度减半,(创建一个小正方形),而不是沿着 (0.5, 0, 0.5) 向量缩放一次(创建一个不再只有 90 度角的形状)
    • ok (0.5, 1, 0.5)?这将使 x 和 z 分量减半,并使 y 保持不变。我想我不清楚为什么 glScale 不起作用。你在找剪刀吗?而不是缩放?
    • 再想一想,您需要做的是通过将矢量沿 x 轴放置的旋转来旋转模型,沿 x 轴缩放任意大小,然后反转旋转。这将允许沿任意向量进行缩放。
    猜你喜欢
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 2012-08-29
    • 2020-11-10
    • 2019-08-21
    • 1970-01-01
    相关资源
    最近更新 更多