Hello everyone,
I got into the problem of finding the best fit cylinder for single-curved surfaces.
This problem is not new, and I found a solution for it from 2017:
Hi Bogdan - I might extract an isocurve from each direction of the underlying surface and sample each with some points - or check for linearity first - then try to fit a circle to the points sampled.
Hi @pascal ,
I already tried that. It seems like the best fit curve is not parallel with the isocurves. This is visible by both comparing with the above solution and also with “naked eye” observation.
@pascal , finding the best fit cylinder optimizes the manufacturing work for single-curved surfaces by using the radius to mechanically bending them in one direction first.
After this initial bend, it is much easier to adjust the torsion manually by twisting the edges into place.
This method can be used when building things like ships, planes, facade panels on Frank Gehry buildings etc.
Therefore I would still like to have a McNeel grasshopper component for it.
Should I hope for one coming in the near, or distant future ?
Kind regards.
I’m trying to put something up… but I’m going for a method that use points only as input.
Using osculating circles is possible only when you have a nurbs surface.
Also your first method, it uses normals. You might not have normals.
Only points.
A point cloud, a 3d scan, etc.
Building up a method for surfaces only seems a bad investment, as you will still lack for a method when meshes or pointcloud will appear.
@René_Corella
Noh, because the UV point at 0.5 ; 0.5 does not necessarily best describe the curvature of the surface. The curvature changes along the surface, therefore you have to find the average.
Also the best curvature direction is not parallel to the U nor the V curves.
The initial surface is not a cylinder.
It is defined by curves in one direction and lines in the other direction.
So, with my method:
I am taking sample points on the surface.
Create some Osculating Circles for those poins (Osculating circle - Wikipedia)
Find the Average Radius for them.
Makes sense - you did say you were fortunate to have a surface, and that you’ll be applying this to multiple surfaces. Are these other surfaces similar to the one in this file, meaning your current method should be sufficient?
Or, as you/Riccardo discussed, will you be working with point sets where a reference surface isn’t present?
This makes me curious about ‘shape detection’ (equally ignorant) when dealing with point clouds.
For a quickie, I baked the 50 points you populated the surface with, turned them into a point cloud, and exported them as a .ply to use within CloudCompare. It has an option to compute normals, and then use ‘shape detection’ - which can be told to fit primitives, such as a cylinder, plus other parameters. Tried it. Didn’t work
For me it is enough at this point using the average Osculatig Circle. I have curved nurbs surfaces which are just torsioned. @maje90 said that he would like to try something using only points. But in my case, I have what I need.
Ok, so… local normals in a way or another must be found.
Math way probably go there too, but way too complex (eigenvalues, etc etc…)
Here’s a hack (that maybe also other have done, I did not check other’s work ):
pick the normals (or calculate a raw equivalent as I did here) and use those normals as points for a circle fit operations. The plane of that circle is a good initial guess!
(if your starting points+normals are from a perfect cylinder, this step should already return the original cylinder plane!)
Then the rest is just thinning the result with some brute force iterated…
This whole script heavily rely on Rhino/Grasshopper circle fit to points function/component.
PS doing the same trick by fitting normals as points with circle fit but while searching best fitting cone surface, should be “simple” as the resulting circle center would result displaced from 0,0,0 (while for cylinders it should always converge to 0,0,0…). As the circle is unitary, calculating the initial guess of the cone angle should be an extremely simple step.