Sorting according to clockwise point coordinates

前端 未结 7 2181
别跟我提以往
别跟我提以往 2020-12-16 18:18

Given a list in Python containing 8 x, y coordinate values (all positive) of 4 points as [x1, x2, x3, x4, y1, y2, y3, y4] ((xi, yi) are x and y coo

7条回答
  •  不思量自难忘°
    2020-12-16 18:43

    What we want to sort by is the angle from the start coordinate. I've used numpy here to interpret each vector from the starting coordinate as a complex number, for which there is an easy way of computing the angle (counterclockwise along the unit sphere)

    def angle_with_start(coord, start):
        vec = coord - start
        return np.angle(np.complex(vec[0], vec[1]))
    

    Full code:

    import itertools
    import numpy as np
    
    
    def angle_with_start(coord, start):
        vec = coord - start
        return np.angle(np.complex(vec[0], vec[1]))
    
    
    def sort_clockwise(points):
        # convert into a coordinate system
        # (1, 1, 1, 2) -> (1, 1), (1, 2)
        coords = [np.array([points[i], points[i+4]]) for i in range(len(points) // 2)]
    
        # find the point closest to the origin,
        # this becomes our starting point
        coords = sorted(coords, key=lambda coord: np.linalg.norm(coord))
        start = coords[0]
        rest = coords[1:]
    
        # sort the remaining coordinates by angle
        # with reverse=True because we want to sort by clockwise angle
        rest = sorted(rest, key=lambda coord: angle_with_start(coord, start), reverse=True)
    
        # our first coordinate should be our starting point
        rest.insert(0, start)
        # convert into the proper coordinate format
        # (1, 1), (1, 2) -> (1, 1, 1, 2)
        return list(itertools.chain.from_iterable(zip(*rest)))
    

    Behavior on some sample inputs:

    In [1]: a
    Out[1]: [1, 1, 2, 2, 1, 2, 1, 2]
    
    In [2]: sort_clockwise(a)
    Out[2]: [1, 1, 2, 2, 1, 2, 2, 1]
    
    In [3]: b
    Out[3]: [1, 2, 0, 2, 1, 2, 3, 1]
    
    In [4]: sort_clockwise(b)
    Out[4]: [1, 0, 2, 2, 1, 3, 2, 1]
    

提交回复
热议问题