Reputation: 91
I have a plane between 3 points and want to get a transformation matrix which allows conversion of other points in the plane to 2D coordinates. What might be of influence is that the plane that points A B and C form does not go through the coordinate system's origin.
I have tried adapting the following answer https://stackoverflow.com/a/49771112/13620003 into the following code:
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;
}
However unlike https://stackoverflow.com/a/49771112/13620003 states, if I apply the matrix to a point in the plane the z component of the resulting point is not 0, and still denotes the original height(z) of the point. If anyone can spot the error, or suggest Unity specific improvements it would be much appreciated.
Upvotes: 2
Views: 1279
Reputation: 91
Figured it out, I was able to adapt the first part of this answer https://stackoverflow.com/a/52163563/13620003 (major credit to @Spektre for his excellent answer) into the following implementation (could use some optimization tough):
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)
);
}
When inputting the global coordinates of points A B and C (as point0, point1 and point2) into the method, the resulting matrix matrixM
can be used to convert coordinates in the global coordinate system to the local coordinate system using var localCoordinate = matrixM.inverse.MultiplyPoint3x4(globalCoordinate)
.
If the globalCoordinate
resides in the plane described by points A B and C global coordinates the resulting localCoordinate
will have a z component of 0.
You can also convert local back to global coordinates using var globalCoordinate = matrixM.MultiplyPoint3x4(localCoordinate)
Upvotes: 3