我有一个3点之间的平面,我想要得到一个变换矩阵,这个变换矩阵允许将平面上的其他点转换成二维坐标。可能有影响的是指向A、B和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的具体改进,我将不胜感激。
弄清楚了,我能够将这个答案的第一部分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)
);
}
将A点、B点和C点的全局坐标(如point0、point1和point2)输入到方法中,得到的矩阵matrixM
可以通过var localCoordinate = matrixM.inverse.MultiplyPoint3x4(globalCoordinate)
将全局坐标系中的坐标转换为局部坐标系。
如果globalCoordinate
位于由点A B和C全局坐标描述的平面上,则所得localCoordinate
的z分量为0。
还可以使用var globalCoordinate = matrixM.MultiplyPoint3x4(localCoordinate)
将本地坐标转换回全局坐标