title: Fit Curve-Spline to 3D Point Cloud
body: <h2>Objective</h2>
  <p>I have a 3D facet model (e.g. .off file) which can for example look like a pipe/tube (see example picture). The goal is to derive an approximate spline (best case combination of lines and splines) which represents the 3D skeleton of this tube using python.</p>
  <h2>State of the art</h2>
  <p>Stackoverflow posts in same field:</p>
  <ul>
  <li><a href="https://stackoverflow.com/questions/35273741/how-to-fit-a-line-through-a-3d-pointcloud">how-to-fit-a-line-through-a-3d-pointcloud</a></li>
  </ul>
  <p>General:</p>
  <ul>
  <li><a href="https://www.semanticscholar.org/paper/Fitting-Spline-Curves-through-Set-of-Unorganized-Chougule-Nirgude/941ce29cfe96db23df1c585fba2758806df3e23c?p2df" rel="noreferrer">Fitting-Spline-Curves-through-Set-of-Unorganized Point Cloud</a></li>
  <li><a href="https://github.com/MarcSchotman/skeletons-from-poincloud" rel="noreferrer">Skeletons from point cloud</a></li>
  <li>Powercrust / NN-Crust? I read about those, however I cant find a python implementation and maybe I am too dumb to implement it on my own. As far as I understood, the basis is delaunay/voronoi which I know already. However i dont know any further steps</li>
  </ul>
  <h2>My Approach (so far)</h2>
  <p>Starting from the example facet model (Image 1), I used a python package to convert the 3d model to a point cloud (Image 2). This point cloud can be used for a voxelized representation (Image 3). Consequently, these three types of data are my starting point.</p>
  <p>Basically, this problem does not seem too complicated to me, however I am missing a starting logic. Most of the research papers overcomplicate this for various further-reaching tasks.
  One idea would be to do a PCA to derive major axes of the component, and scan along these axes. However, this doesnt appear to lead to good results in a performant way.
  Another idea would be to use the voxelized grid and detect a path due to voxel adjacencies.
  Another idea would be to use KD-Tree to evaluate closest points to detect the correct planes for defining the spline direction via their plane normals.</p>
  <p>An approach that I tried was to select N random points from the pointcloud and search for all neighbors within a radius (cKDTree.query_ball_point). I calculated the center of all neighboring points. This leads to the result in image 4. The result seems good as first approach, however it is more or less a tuning of the radius parameter.</p>
  <p><em>Image 1:</em></p>
  <p><a href="https://i.stack.imgur.com/kpOqY.png" rel="noreferrer"><img src="https://i.stack.imgur.com/kpOqY.png" alt="Starting point" /></a></p>
  <p><em>Image 2:</em>
  <a href="https://i.stack.imgur.com/2ki7F.png" rel="noreferrer"><img src="https://i.stack.imgur.com/2ki7F.png" alt="Point cloud" /></a></p>
  <p><em>Image 3:</em>
  <a href="https://i.stack.imgur.com/wRHSq.png" rel="noreferrer"><img src="https://i.stack.imgur.com/wRHSq.png" alt="Voxelgrid" /></a></p>
  <p><em>Image 4:</em>
  <a href="https://i.stack.imgur.com/WiwdV.png" rel="noreferrer"><img src="https://i.stack.imgur.com/WiwdV.png" alt="enter image description here" /></a></p>