简体   繁体   中英

Sort vertices of a convex polygon in clockwise or counter-clockwise

I am trying to sort the vertices of a polygon in either clockwise or anti-clockwise manner. I am trying to calculate an average point [x_avg, y_avg] inside the polygon and calculate all the angles of the vertices from the average point. But my code is giving wrong angles. I am using the formula "atan((m1-m2)/1+m1m2))" to calculate the relative angle between the average point and any vertice. Please let me know what is wrong with the code? Or what algorithm can I use to calculate the ordered vertices? Here is the code:

import math

def rounding_polygon(polygon):
    x, y = zip(*polygon)
    print(x,y)
    x_avg = sum(x)/len(x)
    y_avg = sum(y)/len(y)
    angles = []
    print('x_a = ', x_avg, 'ya =', y_avg)
    x1, y1 = polygon[0][0], polygon[0][1]
    m_com = (y_avg-y1)/(x_avg-x1)
    for v in polygon:
        x2, y2 = v[0], v[1]
        m_curr = (y_avg-y2)/(x_avg-x2)
        slope = (m_com-m_curr)/(1 + (m_com*m_curr))
        curr_angle = math.degrees(math.atan(slope))
        angles.append([curr_angle, v])
    angles = sorted(angles)
    vertices = [x[1] for x in angles]
    print('angles = ', angles)
    print('vertices = ', vertices)
    return vertices

polygon = [[1, 5], [4, 1], [7, 8], [7, 1], [1.8, 5.4]]
vertices = rounding_polygon(polygon)

print(vertices)

atan function gives results in limited range (half of circle). To get full angle range -Pi..Pi , you should use atan2 function that takes two arguments - y-difference and x-difference.

Also note that you can compare vertex positions without angle calculations using cross-product where dx1 = x1 - centerx and so on.

cp = dx1 * dy2 - dx2 * dy1

Sign of this value says if vector to the first point lies left or right from the second vector direction (key to sort)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM