How to fix the result of rhinoscriptsyntax.SortPointList command

Hi, friends on the Forum:
I just meet a problem while programming. I try to use a piece of script like follows to get the result, it will return a polyline linked by intersections points in my plan. While, when I use 'SortPointList ’ to sort the sequence of the list of points, the command does not return the result I am looking forward to (see in the picture). I trying to change the ‘tolerance’ parameter, but it still does not work. I guess that should be determined by some internal mechanism of SortPointList. So I want to know if there is any way to fix this problem.

image

I put the code on the next level

import rhinoscriptsyntax as rs
import itertools

def get_directions(curve, direction):
    directions_dict = {
                'north': rs.coerce3dvector([0, 1, 0]),
                'south': rs.coerce3dvector([0, -1, 0]),
                'east' : rs.coerce3dvector([1, 0, 0]),
                'west': rs.coerce3dvector([-1, 0, 0]),
                }
    offset_pt = rs.CurveMidPoint(curve)+directions_dict[direction]
    
    return offset_pt

line_list = rs.ExplodeCurves(x)

line1 = rs.OffsetCurve(line_list[0], get_directions(line_list[0], "north"), 1)
line2 = rs.OffsetCurve(line_list[1], get_directions(line_list[1], "west"), 1)
line3 = rs.OffsetCurve(line_list[2], get_directions(line_list[2], "south"), 1)
line4 = rs.OffsetCurve(line_list[3], get_directions(line_list[3], "east"), 1)

new_list = [line1, line2, line3, line4]

line_pair =  itertools.combinations_with_replacement(new_list, 2)
line_pair_list = [i for i in line_pair if i[0] != i[1]]

intersections = [rs.CurveCurveIntersection(i[0], i[1])[0][1] for i in line_pair_list if rs.CurveCurveIntersection(i[0], i[1]) != None]

rmv_duplicate = []
for i in intersections:
    if i not in rmv_duplicate:
        rmv_duplicate.append(i)

sort = rs.SortPointList(rmv_duplicate)
sort.append(sort[0])

polyline = rs.AddPolyline(sort)

The documentation on rs.SortPointList() (the sort function you’re using) says that it “Sorts list of points so they will be connected in a “reasonable” polyline order”. I don’t know what logic is used to do this, but it isn’t very well suited to what you’re trying to do here.

I tried rs.SortPoints() which sorts points by their X, Y, Z values. To use this method at all, you have to swap 2 of the points in the resulting list (0 and 1, or 2 and 3). This wasn’t very well suited to the problem here either.

The third method I tried was sorting the points by the angle measured from their centroid. This worked fairly well, but could still be made to fail by moving around the points that the input polycurve was constructed from. Some of the failures here could be avoided by changing your code that limits the input polycurve to 4 segments. I will leave this to you if you’re interested in experimenting further with this.

The best method I found to do what you’re trying to do (offset a curve) is to use the Rhino.Geometry. Curve.Offset(plane, distance, tolerance, cornerStyle) method. It requires much less code and seems to work well with any planar curve.

Code is in the attached grasshopper file:
sortpointlist_re.gh (15.5 KB)

-Kevin

Thanks for your help as well as detailed reply! I find this method is effective to some extent. I have tried to use and change the code you offered, and now my problem is solved roughly with your help😁.

I’m trying to edit a larger project. rg. Curve.Offset is a good method to offset a curve, but it is hard to control the orientation of the offset process, which is what I sincerely need. That’s why I use such a complicated method to complete this process…May God forbid such strange needs from appearing in the future😥