- Home /
Converting a 3D polygon into a 2D polygon
Suppose you have a set of coordinates on a 3D plane forming a polygon . I want to convert this 3d polygon into a 2d polygon with same lengths . How do I go about this? Are there any methods in unity that can help me do this
Answer by Bunny83 · Jun 27, 2018 at 10:43 AM
If your points are all on the same plane you just need to project them onto two unit vectors on that plane
To determine the plane normal you can simply calculate the cross product between two edges of your polygon. So just pick 3 points (A, B and C) and do
Vector3 normal = Vector3.Cross(B-A, C-A).normalized;
Next you want to define your first unit vector on that plane. If you don't care about the rotation you can simply use one of the edges. Otherwise you may want to project one of the world axes onto the plane. You should make sure to not pick a direction that is too close to the plane normal
Vector3 u;
If (Mathf.Abs(Vector3.Dot(Vector3.forward, normal)) < 0.2f)
u = Vector3.ProjectOnPlane(Vector3.right, normal);
else
u = Vector3.ProjectOnPlane(Vector3.forward, normal);
To get the second unit vector just calculate the cross product between the first unit vector and the plane normal:
Vector3 v = Vector3.Cross(u, normal).normalized;
Now you can simply project each point of your polygon onto both unit vectors using the dot product. The two resulting values are your 2d coordinates of your points
Vector2 Project(Vector3 aPoint)
{
return new Vector2(Vector3.Dot(aPoint, u), Vector3.Dot(aPoint, v));
}
Keep in mind that the origin will still be the same. So you may want to offset all points by your desired pivot position. If you have the pivot as a 3d point on your 3d plane you can project it the same way as you do with the other points. Just subtract the pivot from all points in the end and they will be relative to that point.
If you need more help you should be more specific about your issue. Note that if the 3d plane is aligned with one of the 3 worldspace planes things could be simplified by quite a bit. Though the solution i've posted here works for arbitrarily rotated planes in space. Though keep in mind that a plane in 3d can be viewed from both sides so the winding order of your polygon may be important. You may need to flip your plane normal
Note that if your polygon points are not in the same plane you will get some sort of distortion. If you're looking for a way to unwrap a 3d mesh that's a completely different topic and doesn't have one generic solution.
@Bunny83 Thanks for that great and detailed answer! That is exactly what I was looking for. Now I am stucking with the reverse transformation. I want to calculate points within the just transformed 2D plane and project these 2d points on my old 3d plane. I googled it but dont find a good approach. Do you have an idea?
Next time when you have a question, please ask a seperate question and do not post an answer. The reverse is even simpler. Since you have 2d vectors and you still have the "u" and "v" vectors you can simply do
Vector3 p = vec2d.x * u + vec2d.y * v;
Of course if you have shifted all your points by a common pivot you have to add that as well. This simple formula in general maps 2d points to a plane in 3d when you have two linear independent unit vectors of that plane.
If you still have trouble understanding basic linear algebra I highly recommend the 3b1b series on linear algebra
Hi and thanks alot for that fast reply! It worked like a charm!
Answer by lucas_la · Sep 04, 2021 at 10:28 PM
This function will do that. You may want to set the reduced dimension to zero to avoid the floating point approximation to zero.
List<Vector3> alignVerticesOnPlane(List<Vector3> vertices)
{
List<Vector3> verticesOnPlane = new List<Vector3>();
//1. Subtract vertices[0] from all points
for (int i = 0; i < vertices.Count; i++)
verticesOnPlane.Add(vertices[i] - vertices[0]);
//2. Find the normalized plane normal
Vector3 A = verticesOnPlane[1];
Vector3 B = verticesOnPlane[2];
Vector3 n = (Vector3.Cross(A, B) / Vector3.Magnitude(Vector3.Cross(A, B)));
//3. Create a quaternion with the normal of the plane and the direction you want it to face
Quaternion rotation = Quaternion.FromToRotation(n, Vector3.forward); //change Vector3.forward to align with other planes
//4. Apply the quaternion rotation to all points
for (int i = 0; i < verticesOnPlane.Count; i++)
verticesOnPlane[i] = rotation * verticesOnPlane[i];
return verticesOnPlane; // =)
}
Your answer
Follow this Question
Related Questions
2d or 3d for better perform on mobile devices? 1 Answer
2D object look at 3D object 0 Answers
3D Video within Scene 1 Answer
UDP app signature? 1 Answer
2D and 3D lights in a scene. URP,2D and 3D lights in scene URP 1 Answer