Python CurveCurveIntersection on list finds less than CollisionManyMany

I need to test a list of many co-planar curves to see if any of them intersect with any other curve in the same list and return True/False values that I am feeding into a Python Script. I was using CollisionMany|Many for this but it is already slow with my sample set of only 399 curves. My final project will be using many more curves so I would like to go ahead and see if I can get around this bottleneck. I thought since I was already using Python I could try to integrate this intersect test in Python as well (also attached as a cluster with internalized data):

import rhinoscriptsyntax as rs

# Define the input parameter
curves = x

# Initialize the result list
results = []

# Loop through each curve in the list
for i, curve_i in enumerate(curves):
    # Loop through each subsequent curve in the list
    for j, curve_j in enumerate(curves[i+1:], start=i+1):
        # Check for intersection between the two curves
        intersection = rs.CurveCurveIntersection(curve_i, curve_j)
        
        # If the curves intersect, add True to the result list and break out of the loop
        if intersection:
            results.append(True)
            break
    else:
        # If the inner loop completed without finding an intersection, add False to the result list
        results.append(False)

# Output the result list
a = results

When I run this on my curves, it returns 334 True values but CollisionMany|Many returns 388. Looking at the outputs, it seems like my code is sometimes assigning True to one curve that is intersecting and assigning False to the other curve. But not all the time.
In this picture I’m selecting the curves that my script says have intersections but a couple that are intersecting are not selected:

Those red curves are in the list my script assigns False to. But they all are in the results from CollissionMany|Many.

I think it might have something to do with how I am enumerating through the list, but I’m not the best with Python so it might be something else. I don’t know how CollisionMany|Many goes about finding all the intersects so I’m unsure of what to change.

If anyone has suggestions to improve this code or a more efficient component I could try instead of CollisionMany|Many I would appreciate it.

Intersections.ghcluster (36.0 KB)

Here’s my version - I get 388…

IntersectingCrvs-MSH.gh (42.4 KB)

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino.Geometry.Intersect as RGI

tol=sc.doc.ModelAbsoluteTolerance
indices=set()
for i in range(len(crvs)-1):
    for j in range(i+1,len(crvs)):
        insec=RGI.Intersection.CurveCurve(crvs[i],crvs[j],tol,tol)
        if insec and insec[0]:
            indices.add(i)
            indices.add(j)
if indices:
    a=[crvs[n] for n in indices]

which was derived from this stand-alone Python script for Rhino:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino.Geometry.Intersect as RGI

def SelIntersectingCurves():
    crv_ids=rs.ObjectsByType(4, state=1)
    if not crv_ids: return
    
    crvs=[rs.coercecurve(crv_id) for crv_id in crv_ids]
    tol=sc.doc.ModelAbsoluteTolerance
    indices=set()
    for i in range(len(crvs)-1):
        for j in range(i+1,len(crvs)):
            insec=RGI.Intersection.CurveCurve(crvs[i],crvs[j],tol,tol)
            if insec and insec[0]:
                indices.add(i)
                indices.add(j)
    if indices:
        rs.EnableRedraw(False)
        rs.UnselectAllObjects()
        [rs.SelectObject(crv_ids[n]) for n in indices]
    print "{} intersecting curves selected".format(len(indices))
SelIntersectingCurves()

Thank you so much for your help, your code works very well. In an attempt to improve my Python I sat down with a friend today that doesn’t know Grasshopper but is very familiar with Python and we walked through your code and mine to see how they compare and why mine didn’t work. I ended up writing a new bit of code that is ever so slightly faster at very large sets of curves and outputs True/False. Its about 2-3 times faster than using CollisionMany|Many:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino.Geometry.Intersect as RGI

tol=sc.doc.ModelAbsoluteTolerance
intersect=set()
for i, crvs_i in enumerate(crvs[0:]):
    for j, crvs_j in enumerate(crvs[i+1:]):
        insec=RGI.Intersection.CurveCurve(crvs_i,crvs_j,tol,tol)
        if insec and insec[0]:
            intersect.add(crvs_i)
            intersect.add(crvs_j)
if intersect:
    a= [n in intersect for n in crvs]

Thank you again for your help!

1 Like