Search code examples
c#vector3drotationquaternions

How to calculate rotation to align System.Numerics.Vector3 with world up vector [0, 1, 0] in C#?


I have a triangle defined by 3 points (System.Numerics.Vector3, I'm not using Unity3d):

A [-0,21090554, 3,81115985, -23,54532623]

B [0,01877949, 3,79133320, 23,49146652]

C [33,08344650, 1,99846101, 0,20934258].

As you can see triangle is slightly tilted and is not parallel to the ground:

enter image description here

I need to rotate the triangle so it will become parallel to the ground (all three points Y coordinates will become the same).

So I need to calculate a rotation to align triangle normal with world up vector [0, 1, 0] (vertical normal on my picture is [0, 10, 0] because [0, 1, 0] vector will be too short to see and to distinguish it from the triangle normal).

I'm new to 3D and have no idea how to calculate a rotation (Quaternion or Matrix I guess) and apply it to all triangle points.


Solution

  • You can use Quaternion.CreateFromAxisAngle to create the quaternion.

    var normal = Vector3 Normalize((A - B) * (C - B));
    var toDir = Vector3.UnitY;
    var axis = normal * toDir;
    
    var angle = Math.Acos(Vector3.Dot(normal, toDir));
    
    var rot = Quaternion.CreateFromAxisAngle(axis, angle);
    

    To rotate the 3 points, you need define an origin first, then use Vector3.Transform transform the points by the quaternion.

    var O = (A + B + C) / 3;
    var Ar = Vector3.Transform(A - O, rot) + O;
    var Br = Vector3.Transform(B - O, rot) + O;
    var Cr = Vector3.Transform(C - O, rot) + O;