Search code examples
c#.netmath3dgeometry

Howto align a 3D surface horizontally on the X and Z axes (as if it is parallel to the ground)


My Winforms app reads from an .STL (stereolitography) file a 3D model (a set of points with XYZ coordinates) given from a 3D scanner. Scanned object is a platform (parallelepiped) on which some multifaceted grains are located. Platform surface can be considered flat and that platform lies on the table (it's surface also can be considered flat).

3D model is tilted along the X and Z axes:

enter image description here

I need to align it horizontally on the X and Z axes as if the platform is parallel to the ground (by adjusting Y coordinate of points):

enter image description here

I suspect it's a standard math problem - but I am not a math expert. So I'm looking for an algorithm or formula.

If it simplifies the task - the point of the geometric center along the X and Z axes (Pcenter) is definitelly located on the platform top surface. And it is necessary to rotate 3D model around Pcenter so that all points located on platform top surface have the same Y coordinate (Pcenter.Y).


Solution

  • So my final solution for 3D model rotation is (with great help of John Alexiou and shingo - thanks):

    1. Determine 3 points that belong to the flat (they should be far apart as there is inevitably some noise in my scan) - they define a triangle.

    2. Calculate the normal vector of the triangle and compute 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);
      
    3. Apply rotation to triangle (and respectively to all my 3D model points):

      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;