【问题标题】:How would one place an object normal to a surface in 3D space?如何在 3D 空间中放置一个垂直于表面的对象?
【发布时间】:2021-03-24 10:22:12
【问题描述】:

假设我有一个立方体或球形表面。我有一个我想“坐在”这个表面上的对象,即对象的 y 轴应该等于表面的法线。为了渲染,我使用了一个转换,它包含一个位置向量、3 个旋转角度和一个比例向量。

之前,我试图计算标准 向量与法线之间的角度,以获得三个角度:a、b、g。然后,我尝试使用这些角度围绕 i、j 和 k 单位向量旋转对象,使其旋转到与法线相等。

我认为这不起作用,因为 arccos 的范围为 [0, 180]。所以我的问题是:为了将我的对象断言为表面的法线,我需要做什么数学运算?

让我也指定对象围绕法线的旋转无关紧要,我只关心对象是否垂直于表面。

关于规范:我正在使用 Java 和 OpenGL,但这更多是基于数学的问题,所以我认为这并不重要。

这是我正在尝试使用的当前代码:

    /**
     * generates a vector of rotation to a vector
     * @param v - the vector
     * @return - a vector containing the x, y, z rotations
     */
    public static Vector3f rotationTo(Vector3f v) {

        float x = Vector3f.angleBetween(new Vector3f(0, 1, 0), new Vector3f(0, v.y, v.z));
        float y = Vector3f.angleBetween(new Vector3f(0, 0, 1), new Vector3f(v.x, 0, v.z));
        float z = Vector3f.angleBetween(new Vector3f(0, 1, 0), new Vector3f(v.x, v.y, 0));

        return new Vector3f(x, y, z);
    }



    /**
     * determines the angle between two vectors in degrees
     * @param v - vector 1
     * @param u - vector 2
     * @return - the angle between
     */
    public static float angleBetween(Vector3f v, Vector3f u) {
        return (float) Math.toDegrees(
            Math.acos(Vector3f.dot(v, u)
            * quickInverseSqrt(v) 
            * quickInverseSqrt(u))
        );
    }



    /**
     * quickly determines the inverse magnitude of a vector using the
     * Fast Inverse Square Root formula
     * @param v - the vector
     * @return - the magnitude
     */
    public static float quickInverseSqrt(Vector3f v) {
        float val = v.x * v.x + v.y * v.y + v.z * v.z;
        float xHalf = 0.5f * val;
        int i = Float.floatToIntBits(val);
        i = 0x5f3759df - (i >> 1);
        val = Float.intBitsToFloat(i);
        val *= (1.5f - xHalf * val * val);
        return val;
    }

【问题讨论】:

    标签: 3d opengl-es-2.0 linear-algebra transformation normals


    【解决方案1】:

    我找到的答案是,我不是在 (i, j, k) 上旋转 3 个不同的时间 (x, y, z),而是通过将垂直分量 j 与法线向量相交来确定旋转轴,并且然后我使用公式 Cos(t)=v·u 找到了旋转角度。然后,我围绕这个轴旋转了一个角度,这样我就可以相应地创建一个旋转矩阵。

    【讨论】:

      猜你喜欢
      • 2017-09-23
      • 2020-07-17
      • 1970-01-01
      • 2019-04-26
      • 1970-01-01
      • 2011-01-25
      • 2023-01-03
      • 2021-07-15
      • 2020-08-21
      相关资源
      最近更新 更多