The title is probably wrong because I don't know enough math to actually describe my problem in a small sentence.
- I have a closed loop of 3D vectors, which I will call '3D polygon'.
- I need to perform a 2D-only operation on it, which will return me a different set of 2D points
- I need to convert those new 2D points back to 3D.
My current attempt is as follow:
- Get a 'best fit' plane that minimizes the chances of making the '3D' polygon self intersect when converted to 2D.
- Get the two perpendicular planes by shifting the plane normal's coordinates
- For each 3D point, get the distances to the planes to get 'axis aligned coordinates'
- Save the Y coordinate for later in a separate variable, use X and Z to do the 2D operations
- Perform the 2D operations
- Get the new 2D points, and get a weighted average of the closest 3 original points to assume the height of the new 2D points
- Multiply the 'axis aligned coordinates' + the assumed height by the respective planes normals to return the 2D point to 3D space.
The issue is, this is not working, the culprit seems to be the part where I get the 'axis aligned coordinates', as reverting them back immediately gives the wrong result
public static List<Vector2> Planify3Dto2DPoints2(Vector3[] points, Vector3 centroid, Plane ply, out Vector3[] oldHeights) {
var pz = ply.normal.z;
var px = ply.normal.x;
var py = ply.normal.y;
Plane plx = new Plane(new Vector3(pz, px, py), 0);
Plane plz = new Plane(new Vector3(py, pz, px), 0);
oldHeights = new Vector3[points.Length];
List<Vector2> m_points = new List<Vector2>();
int i = 0;
foreach (Vector3 v3 in points) {
Vector3 v4 = v3 - centroid;
float x = plx.GetDistanceToPoint(v4);//this part is wrong, attempting to get the v4
float z = plz.GetDistanceToPoint(v4);//vector back from the x, z, y coordinates is not
float y = ply.GetDistanceToPoint(v4);//working. removing x * plx.Normal from v4 before
m_points.Add(new Vector2(x, z));// extracting the z coordinate reduces the error, but does not remove it
oldHeights[i++] = new Vector3(x, z, y);
}
return m_points;
}
public static List<Vector3> Spacefy2Dto3DPoints(Vector2[] points, Vector3 centroid, Plane ply, Vector3[] oldHeights = null) {
List<Vector3> m_points = new List<Vector3>();
var pn = new Vector3(ply.normal.x, ply.normal.y, ply.normal.z);
for (int i = 0; i < points.Length; i++) {
Vector3 mp = MoveInPlane(ply, points[i]);
if (oldHeights != null) {
mp += pn * oldHeights[i].z;//AverageOf3ClosestHeight(points[i], oldHeights); not needed yet, but working fine, it's weighted average
}
mp += centroid;
m_points.Add(mp);
}
return m_points;
}
private static Vector3 MoveInPlane(Plane plane, Vector2 vector2) {
var z = plane.normal.z;
var x = plane.normal.x;
var y = plane.normal.y;
return new Vector3(z, x, y) * vector2.x + new Vector3(y, z, x) * vector2.y;
}