0

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).

halfer
  • 19,824
  • 17
  • 99
  • 186
bairog
  • 3,143
  • 6
  • 36
  • 54
  • If you can select the points that belong to the flat, then fit a plane though those points. The plane coordinates will give you the transformation needed to align the points to the grid. – John Alexiou Dec 23 '22 at 13:53
  • 2
    @John's idea is good. [This question](https://stackoverflow.com/questions/1966587/given-3-points-how-do-i-calculate-the-normal-vector) will tell you how to compute the normal vector of the plane and [this question](https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d) will tell you how to compute the rotation that aligns that normal vector with your world up vector [0, 1, 0]. – evces Dec 23 '22 at 14:30
  • @evces - did I understand correctly that it is enough for me to determine **any** 3 points that belong to the platform top surface, right? I mean enough to compute the normal vector and rotation that I need? Thank you, guys. – bairog Dec 26 '22 at 05:35
  • Yes with 2 caveats - pay attention to the winding order when computing the normal, and you will want points that are far apart as there is inevitably some noise in your scan. – evces Dec 26 '22 at 15:11
  • see [Problem superimposing and aligning 3D triangles](https://stackoverflow.com/a/52163563/2521214) the points selection might be done using [3D OBB](https://stackoverflow.com/a/62284464/2521214) or simply select 2 most distant points `O(n^2)` and then most perpendicularly distant point to the line formed by the found 2 points ... another option is to compute average of weighted (with triangle area) normals (aligned to closer from the 2 directions) that is `O(n)` and should be close to what you want if the flat area is big enough in respect to the scanned mesh – Spektre Dec 29 '22 at 09:44

1 Answers1

1

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;
    
bairog
  • 3,143
  • 6
  • 36
  • 54