首页 > 解决方案 > 我在 3 个点之间有一个平面,并希望获得一个转换矩阵,该矩阵允许将平面中的其他点转换为 2D 坐标

问题描述

我在 3 个点之间有一个平面,并且想要获得一个转换矩阵,该矩阵允许将平面中的其他点转换为 2D 坐标。可能有影响的是点 AB 和 C 形成的平面不经过坐标系的原点。

我尝试将以下答案https://stackoverflow.com/a/49771112/13620003改编为以下代码:

private static Matrix4x4 Get3DPoint3DPlaneAs2DPointProjectionMatrix(Vector3 pointA, Vector3 pointB, Vector3 pointC)
        {
            // Adapted from https://stackoverflow.com/questions/49769459/convert-points-on-a-3d-plane-to-2d-coordinates

            var vectorAB = pointB - pointA;
            var vectorAC = pointC - pointA;

            var vectoruN = Vector3.Cross(vectorAB, vectorAC).normalized;
            var vectorU = vectorAB.normalized;
            var vectorV = Vector3.Cross(vectorU, vectoruN);

            var vectoru = pointA + vectorU;
            var vectorv = pointA + vectorV;
            var vectorn = pointA + vectoruN;

            var matrixS = new Matrix4x4(
                new Vector4(pointA.x, pointA.y, pointA.z, 1),
                new Vector4(vectoru.x, vectoru.y, vectoru.z, 1),
                new Vector4(vectorv.x, vectorv.y, vectorv.z, 1),
                new Vector4(vectorn.x, vectorn.y, vectorn.z, 1)
            );


            var matrixD = new Matrix4x4(
                new Vector4(0, 0, 0, 1),
                new Vector4(1, 0, 0, 1),
                new Vector4(0, 1, 0, 1),
                new Vector4(0, 0, 1, 1)
            );

            var matrixM = matrixD * matrixS.inverse;

            return matrixM;

        }

然而,与https://stackoverflow.com/a/49771112/13620003状态不同,如果我将矩阵应用于平面中的一个点,则结果点的 z 分量不是 0,并且仍然表示原始高度(z)观点。如果有人能发现错误,或建议 Unity 特定的改进,将不胜感激。

标签: c#unity3dlinear-algebra

解决方案


想通了,我能够将这个答案的第一部分https://stackoverflow.com/a/52163563/13620003(主要归功于@Spektre 的出色答案)到以下实现中(可以使用一些优化困难) :

private static Matrix4x4 Get3DPoint3DPlaneAs2DPointProjectionMatrix2(Vector3 point0, Vector3 point1, Vector3 point2)
        {
            // Adapted from https://stackoverflow.com/a/52163563/13620003

            var x = point1 - point0;
            x.Normalize();
            var y = point2 - point0;
            var z = Vector3.Cross(x, y);
            z.Normalize();
            y = Vector3.Cross(z, x);
            y.Normalize();
            var o = point0;

            return new Matrix4x4(
                new Vector4(x.x, x.y, x.z, 0),
                new Vector4(y.x, y.y, y.z, 0),
                new Vector4(z.x, z.y, z.z, 0),
                new Vector4(o.x, o.y, o.z, 1)
            );

        }

当将点 AB 和 C 的全局坐标(如 point0、point1 和 point2)输入到方法中时,得到的矩阵matrixM可用于将全局坐标系中的坐标转换为局部坐标系var localCoordinate = matrixM.inverse.MultiplyPoint3x4(globalCoordinate)

如果globalCoordinate位于由点 AB 和 C 全局坐标描述的平面中,则结果localCoordinate的 z 分量将为 0。

您还可以使用将本地坐标转换回全局坐标var globalCoordinate = matrixM.MultiplyPoint3x4(localCoordinate)


推荐阅读