我有两个向量,分别是多边形的8个顶点的x和y坐标。 我想要对它们进行排序(按顺时针方向),以获得正确的向量(以正确绘制多边形)。
原始向量:
原始向量:
x=[5 5 7 7 9 9 5 7]
y=[8 6 6 8 6 8 10 10]
排序后的向量:x=[5 7 9 9 7 7 5 5]
y=[6 6 6 8 8 10 10 8]
步骤1:查找顶点的非加权平均值:
cx = mean(x);
cy = mean(y);
步骤2:找到角度:
a = atan2(y - cy, x - cx);
第三步:找到正确的排序顺序:
[~, order] = sort(a);
步骤4:重新排列坐标:
x = x(order);
y = y(order);
本文将为您提供 Ben Voigt 算法的 Python 版本(numpy):
def clockwise(points):
x = points[0,:]
y = points[1,:]
cx = np.mean(x)
cy = np.mean(y)
a = np.arctan2(y - cy, x - cx)
order = a.ravel().argsort()
x = x[order]
y = y[order]
return np.vstack([x,y])
例子:
In [281]: pts
Out[281]:
array([[7, 2, 2, 7],
[5, 1, 5, 1]])
In [282]: clockwise(pts)
Out[282]:
array([[2, 7, 7, 2],
[1, 1, 5, 5]])
对于逆时针角度(上半平面,y > 0),角度为正;对于顺时针角度(下半平面,y < 0),角度为负。
这意味着使用Numpy或Matlab的升序sort()将按逆时针方向进行。
可以使用Shoelace公式进行验证
因此,将上述答案调整为使用降序排序,则Matlab中的正确解决方案为
cx = mean(x);
cy = mean(y);
a = atan2(y - cy, x - cx);
[~, order] = sort(a, 'descend');
x = x(order);
y = y(order);
在numpy中的解决方案是
import numpy as np
def clockwise(points):
x = points[0,:]
y = points[1,:]
cx = np.mean(x)
cy = np.mean(y)
a = np.arctan2(y - cy, x - cx)
order = a.ravel().argsort()[::-1]
x = x[order]
y = y[order]
return np.vstack([x,y])
pts = np.array([[7, 2, 2, 7],
[5, 1, 5, 1]])
clockwise(pts)
pts = np.array([[1.0, 1.0],
[-1.0, -1.0],
[1.0, -1.0],
[-1.0, 1.0]]).transpose()
clockwise(pts)
输出:
[[7 2 2 7]
[5 1 5 1]]
[[2 7 7 2]
[5 5 1 1]]
[[ 1. -1. 1. -1.]
[ 1. -1. -1. 1.]]
[[-1. 1. 1. -1.]
[ 1. 1. -1. -1.]]
[::-1]
来反转数组/列表。该算法不适用于非凸多边形。 相反,考虑使用MATLAB的poly2cw()