Divide polycurve into different lengths (mixing chord & segment lengths)

Hello All,

Would anyone be able to help me get a list of points along a curve controlled by specifying a chord length and segment length.
There will be four user inputs:

  1. Selecting lines for the polycurve
  2. Starting point offset from start of curve
  3. Chord Length
  4. Segment (gap) length

The basis of that screenshot was from this topic: Curve point at parameter for different distances

My current graph is based on the solution from that topic, however I required chord length as I plan to insert straight beams at ,say, exactly 63mm long. Curve.PointAtSegmentLength won’t give that exact value when arcs are involved.

I’ve played with Curve.PointsAtChordLengthFromPoint but struggle to use the output from that to then do the Curve.PointAtSegmentLength, and repeat this function along the length of the curve.

Any ideas how to do this?

This is how I would do it, providing two points come that is offset slightly by the gap distance. Spacing would be the distance you want + the spacing value.

You may also want to offset the point by your start value, or perhaps a negative value.

Give it a shot and see where you get to.

I’ve managed to do it but cannot figure out how to make the graph efficient. To complete all points along the curve, my workflow would mean copying & pasting a bunch of nodes until I can no longer fit the points.

Also, Im finding I cannot do a straight copy, I have to edit the code block number that is an input of List.GetItemAtIndex because for some reason the point I require changes index.
And note: One of the points is not the same as Index 0, which I thought it should be.

Is there a way to detect that the points have reached the max amount along the curve without having to copy and paste a varying amount of nodes?

Can you post your graph? I’ll try and set it up to work with list lacing and levels as you shouldn’t have to alter the number but provide a list all the way through.

Graph:
CurveDivideChord&Segment.dyn (56.8 KB)

Thanks again

@jacob.small

Hey Jacob, any luck with this?

The approach is correct, but would require an Imperative Design Script function

CurveDivideChord&Segment-1.dyn (8.0 KB)

def chrSeg (crv,stPr,chrLgt,segLgt)
{
	pr01 = Curve.ParameterAtChordLength(crv,chrLgt,stPr,true);
	cr01 = Curve.TrimByStartParameter(crv,pr01);
	pt01 = Curve.PointAtSegmentLength(cr01,segLgt);
	pr02 = Curve.ParameterAtPoint(crv,pt01);
	return [pr01,pr02];
};

def pnts (crv,stOf,chrLgt,segLgt)
{

	a = 0;
	mx = Math.Ceiling(Curve.Length(crv)/(chrLgt+segLgt))+1;
	stPr = Curve.ParameterAtChordLength(crv,stOf,0.0,true);
	pr1 = [Imperative]
	{
		prm = [];
		while (a < mx)
		{
			prm[a] =  chrSeg (crv,stPr,chrLgt,segLgt);
			stPr = List.LastItem(prm[a]);
			a = a + 1;
		}
		prm1 = List.Clean(List.Flatten(prm,-1),false);
		return prm1;
	}
	pr2 = List.FilterByBoolMask(pr1,pr1<=1)["in"];
	pr3 = List.Flatten([stPr,pr2]);
	pts = Curve.PointAtParameter(crv,pr3);
	return pts;
};
6 Likes

Great solution @Vikram_Subbaiah !

I built a Python based version of this but forgot to come back to post it:

##################################################
######## Configure the Python environment ########
##################################################
import clr, math #import the common language runtime (clr) so we can use .net libraries and math so we can call the ceiling function to round up values
clr.AddReference('ProtoGeometry') #add the Dynamo geometry library to the CLR
from Autodesk.DesignScript.Geometry import Curve #imporot the Curve class form the Dynamo geometry library 

##################################################
##################### inputs #####################
##################################################
baseCrv = IN[0] #the curve we want to set up our point sequence on
segmentPattern = IN[1] #the sequence of lengths
param = IN[2] #the parameter where we want to start our sequence at
if param == None: param = 0 #ensure we have a start parameter

##################################################
###### initial code set up to prep the loop ######
##################################################
len = baseCrv.Length #the overall length of the base curve
patternSum = sum(segmentPattern) #the total length of the pattern
patternCount = math.ceil(len/patternSum) #the number of times the pattern fits in the curve length, rounded up
iterationCount = segmentPattern.__len__() * patternCount #the number of actions we'd have to take iterating over the segment pattern to reach the pattern count
netPoints = [Curve.PointAtParameter(baseCrv,param)] #a list with the point at our starting parameter - chord length points will be appended onto this
i = 0 #starting from zero

##################################################
########### add to the net points list ###########
##################################################
while i < iterationCount: #while i is less than the iterationcount variable, perform the following 
    i+=1 #add one to i
    dist = segmentPattern.pop(0) #remove the first item from the segment pattern 
    segmentPattern.append(dist) #add the removed item to the end of the segment pattern
    param = Curve.ParameterAtChordLength(baseCrv,dist,param,True) #get the parameter at the distance from our current parameter value
    if param>1: #if param is greater than 1
        netPoints.append(Curve.PointAtParameter(baseCrv,1))#add the endpoint to the net points list
        break #break the while loop
    pnt = Curve.PointAtParameter(baseCrv,param) #get the point at the param
    netPoints.append(pnt) #add the point to the net points list
    remainder = 1-param #get the remainder parameter

##################################################
################ configure output ################
##################################################
OUT = remainder, netPoints #send the remainder and net points list to the Dynamo environment

Note that anything which utilizes chord length can have some bad results when curves double back on themselves quickly - verify your results.

6 Likes

Thanks Jacob & Vikram, both of your solutions worked great.

1 Like