Rotate coplanar 3D points to XY

Hi,

I have a set of 3d points. All these points are on same plane. I have the Normal of the plane.

Now I need to rotate them in such a way that the Z value of all these points become zero.

I have googled a lot. I got very few results and most of them are very much mathematical. Few are about Projection and few are with solution with OpenGL APIs.

Please help me

Thanks in advance.

Do you want to simply “smush” the points into the XY plane using their projection? Or are you looking to preserve these points relative to their centerpoint, and place them on the XY plane as they would appear if the plane normal pointed towards the camera?

Hi @Drigax,
Thanks for responding.

I think, I did it. Not sure whether it is buggy or not. It would be great if someone reviews this code.
The code is implemented in C#.

private static readonly Vector3D Z_AXIS = new Vector3D(0, 0, -1);

        public static List<Vector2D> RotateCoplanar3DPointsToXY(IEnumerable<Vector3D> vectors, Vector3D planeNormal, out Matrix4x4? matrix)
        {
            if (planeNormal.EqualsWithErrorRange(Z_AXIS, Constants.EPSILON))
            {
                matrix = null;
                return new List<Vector2D>(vectors.Select(p=>new Vector2D(p.X, p.Y)));
            }

            var rotationAxis = Z_AXIS.Cross(planeNormal);
            rotationAxis.Normalize();
            var rotationAngle = (float)Math.Acos(Z_AXIS.Dot(planeNormal));
            matrix = Matrix4x4.FromAngleAxis(rotationAngle, rotationAxis);
            var transform = matrix.Value;
            var result = new List<Vector2D>();

            foreach (var vector in vectors)
            {
                var newVector = new Vector2D(vector.X * transform.A1 + vector.Y * transform.B1 + vector.Z * transform.C1, vector.X * transform.A2 + vector.Y * transform.B2 + vector.Z * transform.C2);
                result.Add(newVector);
            }
            return result;
        }

Wth is a dot product tbh? What is that even for

As the plane is only 4 points why not recreating it from width and height instead ?

This might be more efficient and simpler ?

Is your project going to be one that uses Babylon.js? If so I will create a playground using some Babylon.js tools

My application is a babylonjs game. but some logic and 3d mesh generation I am doing it in server as it has a lot of CSG related stuff. I cannot do such heavy work at client side as the devices might be low end.

1 Like

Just now tested my above code with more data. It is completely buggy.

Hi @sebavan, the plane may contain any number of points n where n>2.

You need to compute the plane matrix, invert it and multiply each position with it.
To compute the matrix, you have the normal, an origin (let’s say point[0]), vector A which is the difference between point[1] and origin, normalized, vector B (cross product of A and Normal).
The matrix will look like:
A.x, A.y, A.z, 0
Normal.x, Normal.y, normal.z, 0
B.x, B.y, B.z, 0
origin.x, origin.y, origin.z, 1
Invert that matrix, transform each point with it

1 Like