已知列表里的所有点是按照顺时针或者逆时针排列的,现在的目标是判断是顺时针还是逆时针。策略是从这所有点中先选出X坐标最大的即最右边的点,即凸点。然后这个点的上一个点和下一个点和这个最右边的点组成了两个矢量,然后根据这两个矢量的叉积的结果的正负根据右手定则可以判断,如果这两个矢量平行,那么根据这最右边矢量的Y坐标和上一个点的Y坐标可以判断。下面附上代码。
def IsClockwise(pts):
# Find right-most points (must be a convex point)
pts_x = [pt.X() for pt in pts]
pts_x_max = max(pts_x)
ind_pts_x_max = pts_x.index(pts_x_max)
if ind_pts_x_max != 0:
# 不是第一个
ind_prev = ind_pts_x_max - 1
else:
# ind_pts_x_max = 0
ind_prev = -1
if ind_pts_x_max != len(pts_x) - 1:
# 不是最后一个
ind_next = ind_pts_x_max + 1
else:
# 是最后一个
ind_next = 0
# v1: rank->prev, v2: next->rank
v1_x = pts[ind_pts_x_max].X() - pts[ind_prev].X()
v1_y = pts[ind_pts_x_max].Y() - pts[ind_prev].Y()
v2_x = pts[ind_next].X() - pts[ind_pts_x_max].X()
v2_y = pts[ind_next].Y() - pts[ind_pts_x_max].Y()
zval = v1_x * v2_y - v1_y * v2_x # cross product of v1 and v2
# print("zval", zval)
if zval < 0:
return True # 顺时针
elif zval > 0:
return False # 逆时针
elif v1_y > 0: # v1和v2平行
return True # 顺时针
else:
return False # 逆时针
return False # 逆时针