Sort 3D lines so they can be joined eventualluy

This bit of Python might help get things sorted for you @ning.zhouHNQLJ
EDIT: Updated this python to deal with obscenely short curves

########################################
############## Properties ##############
########################################
__author__ = 'Jacob Small'
__version__ = '0.1.0'
__description__ = "Sort a list of curves by the order in which they'd join into a polycurve with variable length connection"
__DynamoBuilds__ = "X.YY.Z, X.YY.Z..."
__ReleaseNotes__ = "POC only - not suitable for production environments without further testing and edge case handling. Currently doesn't handle branching curve sets."
__Dependancies__ = "None"
__Copyright__ = "2026, Autodesk Inc."
__license__ = "Apache 2"



########################################
### Configure the Python environment ###
########################################
### standard imports ###
import sys #add the sys class to the Python environment so we can work with the sys objects
import clr #add the CLR (common language runtime) class to the Python environment so we can work with .net libraries
### basic Dynamo imports ###
clr.AddReference('ProtoGeometry') #add the Dynamo geometry library to the CLR
from Autodesk.DesignScript import Geometry as DG #add the Dynamo geometry class using the alias DG, to ensure no overlap between class calls in Revit or Dynamo
clr.AddReference('DSCoreNodes') #add the standard Dynamo library to the CLR
import DSCore # import the standard Dynamo classes to the Python environment
clr.AddReference('GeometryColor') #add the Geometry color library to the CLR
from Modifiers import GeometryColor #import the GeometryColor class to the Python environment



#########################################
###### Global variables and inputs ######
#########################################
crvs = IN[0] #the initial curve from IN[0] of the Dynamo environment
sortedCvs = [i for i in crvs] #output list to sort later
polyCurve = DG.PolyCurve.ByJoinedCurves([crvs.pop()]) #build a polycurve from one of the curves in the initial curve list



#########################################
############ Code goes here #############
#########################################
while crvs: #whiel there are curves
    #get the next curve
    crvs = sorted(crvs, key = lambda x: polyCurve.DistanceTo(x)) #sort the curves by the distance from the polycurve
    next = crvs.pop(0) #pop the first curve (closest to the polycurve)
    #because we are always going to remove a curve this shouldn't be an infinate loop
    
    #get the next point
    nextPoint = next.StartPoint #get the start point of the next curve
    if next.StartPoint.DistanceTo(polyCurve) > next.EndPoint.DistanceTo(polyCurve): #if the end point is closer to the polycurve than the next point
        nextPoint = next.EndPoint  #set the next point to the end point of the next curve
    
    #get the connection point
    connectPoint = polyCurve.StartPoint #set the connectPoint to the start point of the current polycurve
    if nextPoint.DistanceTo(connectPoint) > nextPoint.DistanceTo(polyCurve.EndPoint): #if the end point of the polycurve is closer to the nextPoint than the connectPoint
        connectPoint = polyCurve.EndPoint #set the connectPoint to the end point of the polycurve
    
    #get the original curve and the next curve, appending a connecting line if needed
    crvSet = [polyCurve, next] #build a list of the current polycurve and next curve
    if connectPoint.DistanceTo(nextPoint) > 0: #if the connect point and next point are not touching
        #connectPoint.Taunt("i'm not touching you", nextPoint)
        crvSet.append(DG.Line.ByStartPointEndPoint(nextPoint, connectPoint)) #append a line between the connect point and the next point to the crvSet
    
    #build the new polycurve
    polyCurve = DG.PolyCurve.ByJoinedCurves(crvSet) #build the polycurve from the curve set (which contains the current polyCurve and the curves found on this past

#note: you might want to just output the polycurve here, but your original question was 'sort the list of curves'
OUT = polyCurve #set OUT to the polycurve

OUT = sorted(sortedCvs, key = lambda x: polyCurve.ParameterAtPoint(x.StartPoint)) #set OUT to the sortedCrvs list, sorted by the parameter of the polyCurve at each respective curves start point