How System.Windows.Media.Media3D.Matrix3D work

本文关键字:Matrix3D work Media3D Media System Windows How | 更新日期: 2023-09-27 17:50:17

像这样定义一个函数似乎很简单

/// <summary>
/// Build 3D transform matrix with image of unit vectors of axes, and the image of the origin
/// </summary>
/// <param name="xUnit">The image of x axis unit vector</param>
/// <param name="yUnit">The image of y axis unit vector</param>
/// <param name="zUnit">The image of z axis unit vector</param>
/// <param name="offset">The image of the origin</param>
/// <returns>The matrix</returns>
public static Matrix3D MatrixFromVectors(Vector3D xUnit, Vector3D yUnit, Vector3D zUnit, Vector3D offset)
{
    var m = new Matrix3D(
        xUnit.X, xUnit.Y, xUnit.Z, 0.0, 
        yUnit.X, yUnit.Y, yUnit.Z, 0.0, 
        zUnit.X, zUnit.Y, zUnit.Z, 0.0, 
        0, 0, 0, 1);
    m.Translate(offset);
    return m;
}
但是测试代码
...
var m = Geo.MatrixFromVectors(vx,vy,vz,new Vector3D(1,2,3));
var result = m.transform(new Vector3D(1,0,0)) //result: equal to vx
...

表示它根本不使用偏移量。如何让它发挥作用?

How System.Windows.Media.Media3D.Matrix3D work

Media3D命名空间中的结构区分了向量和点。Vector3D用于指定空间中与位置无关的值(如Axis、Surface法线、加速度等),Point3D用于指定位置。

因为向量不应该携带位置信息,所以Matrix3D.Transform(Vector3D)不应用偏移量。它只变换向量的方向

如果您传递Point3D而不是Vector3DMatrix3D.Transform(Point3D),它会按预期工作:

...
var m = Geo.MatrixFromVectors(vx,vy,vz,new Vector3D(1,2,3));
var result = m.transform(new Point3D(0,0,0)) // result is 1,2,3
...