Distribution of a module with limited spacing over a defined length

Hello,
Is there a node in a package that does this job?
or how to try to improve my working process.

I attached diagram and 2 pieces of scripts to show how I proceeded.
The process used:


Capture d’écran 2022-06-26 163441

1/(code block 1) My inputs (L_tot, deb, L_tour)
Search for the maximum limit of the number of modules on the length to be crossed (my upper limit)
from this one
2/ verification with a true condition of the number of modules to reach the length, taking care not to exceed (esp<=L_max)
3/ (code block 2) data retrieval and formatting to create a list of relative coordinates in x
4/ Python script: create the list of coordinates in x (I found solution on the forum)

Thanks in advance for the advice (Hope this doesn’t sound like [doing the job for me])

Cordially
christian.stan

I think I need to dig into the While side with Imperative code in a codeblock


Capture taken from the document of Mr. Sol Amour

Am I on the right track then?

Cordially
christian.stan

I’d avoid a while loop or any form of imperative code here, but without the diagram labeled a bit clearer it’s hard to say.

What I think I know:

  • You have a curve of unknown length
  • You have a maximum spacing value
  • You want that spacing value followed for all interior points except the one in the very middle

This leads to more questions then answers:

  • What if the curve is less than one of length of your spacing?
  • What if the curve is exactly one length of spacing?
  • What if the curve is evenly divisible by the spacing (ie there need not be a ‘middle’ section)?

In any case something like this would be a good start:

  1. overallCurveLength % maxSpacing; will give you the remainder to pack into the center length. This utilizes the modulo function (the % symbol) to let you know what the remaining distance after dividing the length would be.

  2. From there we can get the length at the midpoint (overallCurveLength / 2 ), and use that to build a range to 0 to that distance less half the remainder from step 1. This will define the lengths where we’d want a point along the first half of the curve. Something like 0 .. ( overallCurveLength -remainder ) / 2 .. maxSpacing ; would be a good direction.

  3. You can then build the subsequent range from the second half lengths along the curve using something like ( overallCurveLength + remainder ) / 2 .. overallCurveLength .. maxSpacing;

  4. From there you’d want to join the two lists together and pull the unique values to define the lengthList, with something like DSCore.List.UniqueItems( DSCore.List.Join( [ firstHalf, secondHalf ] ) ); to clean up any ‘center points’ which may occur in the case of even division by two.

  5. Finally we can move past the lengths and into geometry (thus far delaying this to ensure we’re doing the ‘hard work’ with the lower level arithmetic as it’s faster than working with geometry) by Curve.PointAtSegmentLength(crv, lengthList);

Overall those samples (I’m not at my computer today so I can’t confirm this works) might be:

overalLCurveLength = crv.Length;
maxSpacing;
remainder = overallCurveLength % maxSpacing;
firstHalf = 0 .. ( overallCurveLength - remainder ) / 2 .. maxSpacing;
secondHalf = ( overallCurveLength - remainder ) / 2 .. overallCurveLength .. maxSpacing;
lengthList= DSCore.List.UniqueItems( DSCore.List.Join( [ firstHalf, secondHalf ] ) );
points = Curve.PointAtSegmentLength(crv, lengthList);
2 Likes

Hello, and thank you for the explanations, I did not get there with your advice (I still need to progress)
I found a solution nevertheless with fewer nodes (I don’t think this is the most optimized)

The codeblock used:

//Inputs
courbe;
L_tot;
L_tour;
deb;
L_max;
n=0;
esp=[];
ctrl=[];
n_born=Math.Ceiling((L_tot-2*deb)/L_tour);
a=2..n_born..1;
Res=[Imperative]
{
	if ((L_tot-2*deb)<=2*L_tour)
		{
		n=1;
		}
	else
		{
		for (i in 0..(n_born-1))
			{
			esp[i] = Math.Round((L_tot-2*deb-a[i]*L_tour)/(a[i]-1),3);
		 		if (esp[i]>L_max)
		 			{
		 			ctrl[i]=0;
		 			}
				else
					{
		 			ctrl[i]=1;
		 			}
		 	}
		n=List.IndexOf(ctrl,1)+2;
		}
return n;
};
espa = (L_tot-2*deb-Res*L_tour)/(Res-1);
rep=DSCore.List.Flatten([deb,(L_tour+espa)..#(Res-1)..0]);
espx=[];
ac=DSCore.List.Count(rep);
espx[0]=rep[0];
Coor_x=[Imperative]
{
	for (i in 1..(ac-1))
	{
	espx[i]=espx[i-1]+rep[i];
	}
return espx;
};
Curve.PointAtParameter(courbe,Coor_x/L_tot);
Curve.PointAtParameter(courbe,(Coor_x+L_tour)/L_tot);

edit:
I modified a line for residual handling (for exceptions if exactly multiple)

Cordially
christian.stan

See if this line achieves the same

courbe.PointAtSegmentLength((deb..(courbe.Length-L_tour-deb)..#(Math.Ceiling((courbe.Length-(deb * 2))/(L_tour+L_max))))<1> + [0,L_tour]);

3 Likes

hello, it sounds obvious when you see the result of the code,
thank you @ you and Mr. Jacob (there was a disguised notion of odd parity that I had not grasped) for looking into my problem, it I still have a long way to go.
I will check for exceptions.
a big thank-you

Cordially
christian.stan

2 Likes

I admit that I don’t understand the result of the following exception (esp < Lmax)
while taken into account in the possible distribution of your code (L_tour+L_max)

cordially
christian.stan

Math.Ceiling ensures that the gap is <= Lmax

1 Like

Hello,
That’s why I’m surprised at the result,
try with the following values
Curve with a Length of 10.800m
deb=0.2m
L_tour=1.20m
L_max=1.50m
and you will have a spacing of 1.867m > Lmax =1.50m

Must be an error on my side it seems then

cordially
christian.stan

Increased the division count by 1

courbe.PointAtSegmentLength((deb..(courbe.Length-L_tour-deb)..#(Math.Ceiling((courbe.Length-(deb * 2))/(L_tour+L_max)))+1)<1> + [0,L_tour]);

2 Likes

Thanks a lot
I adapted your optimized code this way.

2nd code block

b=Point.X(x);
rect=(b[1][0])-(b[0][1])>L_max?1:0;

y=courbe.PointAtSegmentLength((deb..(courbe.Length-L_tour-deb)..#
(Math.Ceiling((courbe.Length-(deb * 2))/(L_tour+L_max)))+rect)<1> + [0,L_tour]);

cordially
christian.stan

1 Like