Search code examples
c#vector3drotation

Rotate faces so normals align with an axis in C#


I have an array of faces, each face has an array of points in 3d space. I want to fill an array of unfolded faces that contains the faces with their normals all pointing along the z axis. DirectionA is the z axis, DirectionB is the normal of the face. I work out the angle and axis then apply it. As I have points, myPoint is a point not a vector could that be a problem? My logic is not right somewhere....

Here is my current code:

    public void UnfoldAll()
    {
        Vector3d directionA = new Vector3d(0, 0, 1);//z axis
        int iii = 0;
        foreach (Face f in faces)
        {
            Vector3d directionB = normals[f.normal - 1]; //normal from face
            float rotationAngle = (float)Math.Acos(directionA.DotProduct(directionB));
            Vector3d rotationAxis = directionA.CrossProduct(directionB);
            //rotate all points around axis by angle
            for (int i = 0; i < f.Corners3D.Length; i++)
            {
                Vector3d myPoint;
                myPoint.X = f.Corners3D[i].X;
                myPoint.Y = f.Corners3D[i].Y;
                myPoint.Z = f.Corners3D[i].Z;
                myPoint = Vector3d.Normalize(myPoint);
                Vector3d vxp = Vector3d.CrossProduct(rotationAxis, myPoint);
                Vector3d vxvxp = Vector3d.CrossProduct(rotationAxis, vxp);
                Vector3d final = directionB;
                var angle = Math.Sin(rotationAngle);
                var angle2 = 1 - Math.Cos(rotationAngle);
                final.X += (angle * vxp.X) + (angle2 * vxvxp.X);
                final.Y += (angle * vxp.Y) + (angle2 * vxvxp.Y);
                final.Z += (angle * vxp.Z) + (angle2 * vxvxp.Z);
                unfoldedFaces[iii].Corners3D[i].X = final.X;
                unfoldedFaces[iii].Corners3D[i].Y = final.Y;
                unfoldedFaces[iii].Corners3D[i].Z = final.Z;
            }
        }
        iii++;
    }

Any suggestions would be great. Thank you.


Solution

  • Thank you that was helpful, here is my code if anyone else needs help:

        public void UnfoldAll()
        {
            Vector3d directionA = new Vector3d(0, 0, 1);//z axis
            unfoldedFaces = new UnfoldedFace[faces.Length];
            int iii = 0;
            foreach (Face f in faces)
            {
                unfoldedFaces[iii].Corners3D = f.Corners3D;
                Vector3d directionB = normals[f.normal - 1]; //normal from face
                directionB = Vector3d.Normalize(directionB);
                Vector3d vxp = Vector3d.CrossProduct(directionA, directionB);
                float rotationAngle = (float)Math.Acos(directionA.DotProduct(directionB));
                Quaternion q = Quaternion.FromAxisAngleQ(vxp, rotationAngle);
                q.Rotate(unfoldedFaces[iii].Corners3D);
                iii++;
            }
        }