Flow polyline on curve

HI , i am trying to flow a polyline ( crv 1 ) along a generic curve (crv 2 )

i need to make sure that the polyline segments are preserving their original lenghts and that start and end points of the 2 curves will be coincident thus through scaling crv2.

I tried ( method 1 ) with Kangaroo2 and it would work at least for getting the vertex of crv 1 laying on crv 2 , it would if it wasnt for the polyline points that are not being flowed always with same direction…yes the vertex are on the guide crv ( crv 2 ) but they ramdomly move back and forward…other problem is that after flowing i don’t know how to scale crv 2 in order to get end points of crv 2 to match end points of flowed crv 1

i also tried ( method 2 ) by flowing crv 1 on a scaled crv 2 but as expected the lenghts of the segments ( crv 1 ) are not preserved because the scaling factor is wrong and probably fowing is not preserving lenghts

attached you can find the definition with the 2 methods, if anyone can help me to fix the bug on method1 or if anyone know any alternative solution to solve the problem i aprpreciate.

20240324 FLOWING POLYLINE ON CRV.gh (21.2 KB)

you only use the length(s) information of the polyline (segments) / crv_1 ?
is this right ?
you need a 2d only solution ?

maybe assign grasshopper category to your topic so you attract the right people.

I would solve this with text based programming / scripting and use nested interval to find the final scale factor.

Do you only need this approach once ? or many times ?

yes , i understand this is not enough but i don’t know which goal to use in order to maintain the proper orientation ( order ) of the polyline points along crv 2

yes there is a unique solution if the rules are respected …the goals are :

  1. lenghts of the segments on crv1 does not change
  2. crv 1 is mapped ( flowed ) on scaled crv 2
    3 ) crv 2 must be scaled within respect its starting point and in order to get its end point matching end point of the adapted crv 1 ( adapted = flowed along scaled crv 2 )

you are right , let me apologize , i have just corrected it.

i see what you mean , this is a classic way , it makes sense but i am not skilled with written code , i also think that GH has the potential and tools to achieve the goal , K2 seems one of the possible tools , i am sure K2 can get the job done once i fix the problem mentioned above , i think that Hoopsnake could also be used to realize your logic. i just wonder if anyone have some suggestion/trick ( mapping or similar ) to find a precise solution without use of incremental loops which, apart from having and intrinsic error which depend on the tolerance applied to the increment for the loop, seems to be quite slow if you use very small values for the increment.

thanks , cheers

can you sketch the expected outcome?

… well if you use kangaroo - you just delegate this “incremental work” to it.

nested loops is not about incremental steps, its about having two values that narrow from both sides - typically implemented with recursion - and as a rule of thumb 2 or 3 levels of recursion will result in 1 digit of (decimal) precision - or even faster.

this is a simple example of calculating a Square-root with recursion.
in 37 steps i get 12 digits of precision

using System;
public class Program
	// recursive function
	// search between a and b
	private static double SqrtFinder(double sqrtMe, double a,double b, double tolerance, int level)
		// todo check that a is smaller b
		int maxLevels = 50; // backup recursion stop if algorithm is wrong
		double test = (a+b) / 2.0; // mid of a and b
		double testSq = test*test;
		double delta = sqrtMe - testSq;
		// stop if level is to high or tolerance reached
		if (level > maxLevels || Math.Abs(delta) < tolerance)
			Console.WriteLine("result at level {0}", level);
			return test;
		// recursion
		if (delta < 0)
			// testSq is to big - search in Interval a..test
			return SqrtFinder(sqrtMe,a,test,tolerance,level+1);
			// testSq to small - search in Interval test..b
			return SqrtFinder(sqrtMe,test,b,tolerance,level+1);
	// function to start recursion
	public static double Sqrt(double x, double tolerance)
		// bad values - minimal input test
		if (x <= 0.0)
			return Double.NaN;
		// start the recursion
		return SqrtFinder(x,0,x,tolerance,0);
	public static void Main()
		double x = 9.0;
		double xSqrt = Sqrt(x,1.0e-12);
		Console.WriteLine("sqrt of {0} is {1}", x, xSqrt);

a lot of stuff regarding (nurbs) geometry and calculation of intersections for example is done in similar fashion…

See image below

dashed crv is the original guide crv ( crv 2 ), the flowed crv ( crv 1 ) is laying over a scaled version of crv 2

the expected result is in red ( the lenght on original crv 1 and flowed one are the same )

i see, so the shape of the curve1 doesn’t matter at all, just the segment length. and you want to convert curve2 into polyline. got it

thanks for the example

asi said i have little experience with functions and written code in general , the only loops i did where very basic loops made with hoopsnake and the increment ( step ) was a value decided by me, the smaller the value , the finer the result , the longer the calculation time.

all i can say is that it was quite slow.

I have been trying to study python but it giving me a much harder time if compared with GH and at the time i am driven by need to solve this problem .

thanks for the example , i will try to make practice on it

well…yes , we are saying same thing in 2 different ways , what you call converted crv2 in my mind is the deformed crv 1 but yes , as you write we can state that the result is a poliline that lay on a scaled version of original crv2 and the segments lenght are equal to those on crv 1

in my mind K2 is one of the option that can handle this problem but while the lenghts are preserved we have that points on crv are not flowing along the domain ( t) of crv from 0 to growing values of “t” but are pulled forward and back…other problem would be to establsh a goal to get proper scaling value of crv2

i think that the more elegant solution is the one proposed by @Tom_P but as i siad im stuck when it comes to written scripting

this is the equivalent topic

awsome !!! thanks for suggesting this post i really appreciate !!! , tomorrow i will study it !!!


is this what you re after ?
(I used a script to find it - with recursion and a tolerance of 1.0e-12 in 27 ms)

please notice that the second segment has an additional point.

divide_and_scale_00_rh7.3dm (60.7 KB)

with Kangaroo I would do something like this:

[I think I need to add Anchors to start/end… will update the file]

1 Like

nice approach.
I like that you first scale the polyline and convert the absolute distances to relative ratios.
(which is a bit hidden by the orient-component) - so kangaroo actually solves a bit another problem:
how to divide an entire curve by straight segments in given ratios.

and finally scale everything back to solve the question.

just wondering, if you set the tolerance of the solver to 1.0e-12 and turn on profiler, how much time does the solver need ?

1 Like

my solution is way off :slight_smile:
what you have seen in my above post is wrong due to the fact that start/end points were not forced to stay at the very start/end points of the nurbs curve
that’s why my ratios were perfect(ly wrong) :slight_smile:

actually, I figured that problem just because I opened the Rhino file you posted to doublecheck results, and saw mine were different :slight_smile:

I think a custom Kangaroo Goal is needed for this case, where all the lines lengths get scaled alltogether (I’m not able to script it, at all :smiley: )

the only thing I can think about is divide and conquer an initial “candidate domain” of scaling values, which looks like on very same leit motif of your recursive solution

I re-attach my GH file like donating my body to science :slight_smile:
Flow_scale_inno.gh (28.2 KB)
[the file includes the final curve from your solution on the bottom, because they are perfect, so they are a good testing bench for further explorations]

another manual, modelling solution - no scripting, no grasshopper.

divide the target-curve with the given distances (red circles).
scale the target curve and move it up (i used 100 mm)
now loft the curves to get the surface.
This (all-scale-factor-)surface represents different scaling-factors…
(it also would be possible to use ExtrudeToPoint)

now, for each circle:
For the first circle, the “alongCrv” is the left edge.
Intersect the new surface with the “all-scale-factor-surface”.
the right intersection-curve (blue) is the “alongCrv” for the next circle.
( I deleted all surfaces, as it would be a big mess)

now the last intersection-curve will intersect the edge (red) at the right.
this is the correct height and therefore scale-factore.
the Isocurve at this height is the searched curve.
intersecting it with the "alongCrv"s are the polylinePoints.

divide_and_scale_manual_00.3dm (3.5 MB)

@inno divide and conquer is the same as i meant with nested interval / recursion - not sure if I used the right term.

buona notte a tutti

kind regards -tom


LengthRatio is the Goal you need for this in Kangaroo

lengthratio.gh (13.9 KB)


I need to study SO MUCH MOOOORE… :+1:

as speed/result comparison (@Tom_P )
Flow_scale_DanielPiker_LengthRatio.gh (30.0 KB)

1 Like

thats it , correct!!! :slight_smile:

woww its very efficient !!! as i said i am not skilled with scripting but im trying to learn more , the learning curve with written code is much flatter than GH and i’m quite stuck to be honest

if you ever could share the script that could be a very good learning source for me , thanks for considering sharing.

@Tom_P @inno I want to thank sooo much for placing so much effort on this challenge , i am delighted by the quality of your approaches and proposals to solve the problem,
I am not as skilled as you are but you discussion is super interesting and it’ll keep me busy tonight to study it and learn something new

Thank You very much , i really appreciate !!!

( ps sorry for not taking part to the debate but i have been traveling all day with no chance to partecipate )

Thanks @DanielPiker , i never had a chance to use the lenght ratio goal before and i didnt know how to use it, this is super useful !!! Thank You very much.

i catch the opportunity to ask you if there is any chance for you to release an in depht manual on kangaroo2?
K2 it a tool with huge potential and i am sure that there is a limitless number of fields where it can find application but as a beginner i am struggling because, despite having found tons of instructional tutorial on the web ( all very similar i have to say ) and despite having purchsed some paid K2 course , i feel like we still don’t know the true potential and mostly because of the lack of high quality learning material.
True the McNell forum is amazing and i cannot stop to thanks all users for keeping it so active but i think that a complete handbook with an organized workflow , from basic theory , to goal explanation to end with practical examples would be a bless for all of those like me.