Interesting - it looks like when the curvature is tight enough/the segments long enough, it can get trapped in a local energy minimum which is not the global minimum.
One way to nudge it out of this configuration would be to use the grab tool.
Connect the ‘Grab’ component to the {0;0} input of the Entwine, then
hold down the Alt key and use left mouse button to drag the point in Rhino.
Sorry for bumping up this old thread, but I had this problem and started to code a solution, then I found this thread but I’m not sure of if the problem was solved already?
For my own part I have need for a single simple component since I often need these straight segments, so I coded a single component for this, and no surprise, I also encountered all the tricky cases discussed in this thread. I have not tried all the solutions posted here but I post mine as well.
My single component finds the segments of a set length using circles (most common strategy I guess) and optionally it auto-extends the segment length (input Extend = true) to cover the full length of the curve (within document tolerance).
Fig 1. The component.
Fig 2. Dividing the curve segements using circles (from left to right). It avoids getting messed up at self intersections. Here the segments are not extended.
Fig 3. Here the curve segments are extended to cover the entire base curve. The numerous circles indicates that the component iterates extending the circle radius until it ends up within tolerance distance from the end of the curve. Red and green points indicate the different segments landing points after extending.
Sometimes it happens that the algorithm goes bananas when it extends too much (the radius inflates more than needed to consume the rest-distance to the curve end), then the Refine option fixes it by iterating with smaller increments when extending. This seems to work in most cases (haven’t seen it fail in my testcase):
Fig 4. Here the circles has “inflated/extended too much” (this problem was fixed above by activating the Refine option) because it missed the tolerance +/- interval at the curve-end, and therefore the iterator didn’t stop until it reached a max_iterations guard in the algorithm (I have yet to figure out how to detect a miss so I can revert it, but at least the Refine option can handle it after the fact.
Fig 5. Here the end segment which reached the end of the base curve.
Fig 6. One of the tricky things was to avoid “jumps” over selfintersections or “shortcuts” at tight loops. Here the segments attach to the curve without shortcutting, as long as the segment lengths fits into the loop:
The component:
DivideCurveByStraightSegments.gh (24.1 KB)
// Rolf
RIL, nice solution.
It’s a very interesting code.
It works on planar XY plane.
It would be nice have it work also on a curve in the 3d space; perhaps using sphere instead circles.
Hi @arch.mariosacco, glad you liked it.
The code (script component) is quite extensively documented so it should be easy to modify it to create Spheres instead of circles and use Intersection.CurveBrep
instead.
.CurveBrep
returns Point3d[¤] so it shouldn’t take much modification of the code illustrated below.
Feel free to modify and upload a 3D version!
// Rolf
Hi again @arch.mariosacco,
I made a 3D version of the CurveToLines component. It’s slower than the 2D but it sems to work. Both versions in the attached file below:
BTW, the Custom Preview components in the Gh definition consumes memory (at least for me). This happens to my memory after scrolling in the Viewport a little bit… :
Edit: Replaced with last version (bugfix first segment):
CurveToLines_Component_2D_3D.gh (27.2 KB)
// Rolf
Thank you very much; I’ll try as soon as possible.
I have no idea where these come from but in my tool palette I have three DivideCurve components.
- 1st one is native and it divides by the segment length
- 2nd one divides curve by number of segments with equal distances between knots
- 3rd one divides curve by predefined distance between knots
WOW, I have never seen them!
On top of these 3, I have this:EqualizeSegmentsDivide
it’s a cluster in a matter of fact, works great by dividing any curve by predefined number of equidistances.
Author: Saeid Abbaspoor, Folding World
I don’t know which component version of Saeid Abbaspoor’s component you have, but for me the component I downloaded (from this page) doesn’t really divide the curve consistently equidistant (the curve I used for testing, a really nasty curve, I promise). Example:
Fig 1. The component I made (magneta) is significantly more consistent than the one by Saeid Abbaspoor (yellow):
Fig 2. Segment lengths vary with “jumps” (Saeid Abbaspoor’s component):
My component can be better still (it misses the first shortest segment in the current version, but the rest of the segments are fairly good, and they’re all consistent length, with deviation typically less than 0.0000 mm. The length consistency of my component:
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963472
27.963577
Fig 3 Summary of the most important differences between the “native” components and the one I made:
In order to divide the curve to match both curve ends, and to get equally long straight line segments, without short cut jumps, it takes an iterative approach, and some logic to examine which intersection to use in each case (each division attempt can give multiple divisions to pick from)
// Rolf
I never tested it so deeply, never had to. Thanks for your insight.
FIXED
I now fixed the components so that the first segment is the nearest division along the curve (no crossover jump). So now all segments are the “nearest” equally long line segments without jumps over narrow loops. 2D and 3D versions included in this fix.
CurveToLines_Components_2D_3D.gh (27.2 KB)
// Rolf
Great Work RIl.
I think Piotr were joking and I was joking too.
I know well the GH components on division but they don’t work as your C++ component does.
The exact division in equal segment is real complex procedure you can’t automatically achieve with standard GH components.
But…I hope some one find a more simple trick to solve the problem.
The problem is divide any curves in equal length segments given the numbers of segments. Simple to say, difficult to do.
I just made the shocking discovery that Dynamo has a native component “points by cord length” that does this painlessly (planar only I presume)
Hi Piotr, where did you find that EqualizeSegmentDivide? I cannot find it in my grasshopper
Hey @Geneses,
Here is a sample that just uses Python.
test_divide_equidistant.gh (3.6 KB)
# Calculates 3d points on a curve where the linear distance between the points is equal.
a = None
if curve:
length = curve.GetLength()
if distance > 0.0 and distance < length:
a = curve.DivideEquidistant(distance)
– Dale
Thank You Dale, I have found what he have shown but it seems it is an .exe file when downloaded
+ equalizesegmentsdivide.ghuser (8.3 KB)
Why the extension is ghuser? How to install it?