使用 DirectXTK / DirectXMath 转换平面

Transforming a plane with DirectXTK / DirectXMath

我有一个由三个点定义的 3D 平面,我想使用 DirectXTK 将其转换为 4x4 矩阵。

我尝试了两种方法:

  1. 用 Plane::Transform() 方法变换平面 - 这给出了一个非常奇怪的结果。

  2. 变换三个点并从变换后的点创建一个平面 - 这很好用。

我也尝试在调用 Plane::Transform() 之前转置矩阵,它使平面法线正确,但常量是错误的(另外,转置矩阵对我来说真的毫无意义)。

void TestPlaneTransform()
{
    Vector3 p1(-2.4f, -2.0f, -0.2f);
    Vector3 p2(p1.x, p1.y + 1, p1.z);
    Vector3 p3(p1.x, p1.y, p1.z + 1);

    Plane plane(p1, p2, p3);
    Matrix m = Matrix::CreateTranslation(-4, -3, -2);

    // transform plane with matrix
    Plane result1 = Plane::Transform(plane, m);

    // transform plane with transposed matrix
    Plane result2 = Plane::Transform(plane, m.Transpose());

    // transform points with matrix
    Vector3 t1 = Vector3::Transform(p1, m);
    Vector3 t2 = Vector3::Transform(p2, m);
    Vector3 t3 = Vector3::Transform(p3, m);

    // plane from transformed points
    Plane result3(t1, t2, t3);

    result1.Normalize();
    result2.Normalize();
    result3.Normalize();
}

标准化后的结果如下:

result1 x:-0.704918027 y:-0.590163946 z:-0.393442601 w:0.196721300

result2 x:1.00000000 y:0.000000000 z:0.000000000 w:-1.59999990

result3 x:1.00000000 y:0.000000000 z:0.000000000 w:6.40000010

Plane::Transform() 调用 XMPlaneTransform,它是 DirectXMath 库的一部分,其文档简单地说 "Transforms a plane by a given matrix."。我想这个方法很好,但是我的代码有什么问题?

来自规格:

要变换的规范化平面。在调用此方法之前,此 Plane 必须已经归一化,以便其法向量具有单位长度。

我猜用未规范化的平面调用此方法会产生某种垃圾。所以我先把飞机归一化再检查。

Plane.Transform Method (Plane, Matrix)

由于您是在 DirectXTK Plane 上调用 Transform,因此似乎不需要在调用之前对其进行规范化。 但是 Plane::Transform 的 DirectXTK wiki 指出:

平面应通过矩阵的 逆转置 进行变换,对于纯旋转,其结果与原始矩阵相同。

github.com/Microsoft/DirectXTK/wiki/Plane