# Joining Curves Recursively

CurveJoinRecursion.gh (54.8 KB)

Say you have a list of overlapping curves in two dimensions (see attached image). Given a start curve index and end curve index, how would you go about recursively joining the curves to achieve a connection between the desired start and end curves? I imagine using a recursive function in python could accomplish this, but am curious what type of solutions people may come up with for writing this in python. The goal would be able to have several start curve segments and join that curve to a list of possible end segments in every possible way through a network of disjoint curves.

I’ve attached a GH script with some example geometry and started by trimming the curves at every intersection with every other curve. Any help would be greatly appreciated and I’m curious to see what solutions people come up with as I’m still becoming familiar with python. Thanks!

To help people respond, please could you clarify whether the segments are directed? I.e. can you only travel away from the start node(s), or can you create loops by travelling segments in the reverse direction as here?

Hi Jeremy,

You could technically create loops, so the goal would be to filter out only the curves that successfully join to the end index curve.

Here’s where I’m at so far. It works until the curve that it attempts to join with is flipped in the wrong direction, producing an issue with the domain statement. Will continue to work on it later today.

``````import rhinoscriptsyntax as rs

rcCrvs = []

#start by collecting initial curves
for i in y:
rcCrvs.append(x[i])

#good curves to select
filterCrvs = []

for c in rcCrvs:
domain = rs.CurveDomain(c) #   get domain of newly joined curve
for i, p in enumerate(x): # test with curve pool
ccx = rs.CurveCurveIntersection(c,p) # test for intersection
if ccx != None and ccx[0][0] != 2: #filter out only the results that occured at points and not overlap
if int(ccx[0][5]) == int(domain[1]): #check to see if the interesection happens at the end of the curve joined curve
join = rs.JoinCurves([c,p]) # join new segment to curve
if i in z and len(join) == 1: #add joined curve to output list
filterCrvs.append(join[0])
elif len(join) == 1: #otherwise add it back into the search list
rcCrvs.append(join[0])
else:
print ('crv failed to join')

a = rcCrvs
``````

Sorry, I’m not clear whether you mean
a) you have a requirement to allow loops (provided you get to an end point) or
b) you have a requirement not to loop but see the potential for loops as an implementation problem you have to develop around.

If you don’t want loops then your graph is directed (each link can only be traversed in one direction).

If you do want loops then you probably want to ensure that you only go round a loop once in a specific path (in my example the red arrows delineate an infinite number of traversals if you don’t constrain circuits of the loop part). Given that you can have loops in different places along the path you cannot simply say I’ll do this loop once only. Allowing loops makes the problem much more complicated…

Ah, I’m realizing the issue you are pointing out now. B is preferred as loops are not desired, I would ideally have only the most direct routes between the start and end segments.

Update: I have gotten a working version on a small sample of curves, but unfortunately I’m getting some major hang time when I do it with a bunch of curves. Is anyone willing to take a stab at reducing the computational cost of this script?

Network Join.gh (10.4 KB)