Python 将矩形的顶点按顺序排列
我正在尝试用python(2.7)编写一个函数。 此函数将获取代表顶点坐标的8个值的列表。Python 将矩形的顶点按顺序排列,python,algorithm,sorting,math,geometry,numpy,scikit-image,Python,Algorithm,Sorting,Math,Geometry,Numpy,Scikit Image,我正在尝试用python(2.7)编写一个函数。 此函数将获取代表顶点坐标的8个值的列表。 (输入的形式是[Ax,Ay,Bx,By,Cx,Cy,Dx,Dy]) 该函数将确定是否给定这些顶点以形成有效的矩形 如果没有,它会将它们按顺序排列,并返回这些顶点的排序列表。 起点或方向(顺时针或逆时针)并不重要 让我举例说明我想要什么: 如果给定的输入在下面的链接中形成第二个或第三个形状;函数将把它转换为第一个。 我可以使用哪种算法来执行此操作? 我使用了Alexey建议的方式并编写了代码。 它可以采取
(输入的形式是[Ax,Ay,Bx,By,Cx,Cy,Dx,Dy])
该函数将确定是否给定这些顶点以形成有效的矩形 如果没有,它会将它们按顺序排列,并返回这些顶点的排序列表。 起点或方向(顺时针或逆时针)并不重要 让我举例说明我想要什么:
如果给定的输入在下面的链接中形成第二个或第三个形状;函数将把它转换为第一个。 我可以使用哪种算法来执行此操作? 我使用了Alexey建议的方式并编写了代码。 它可以采取一些优化,但它不是我的必要条件
def crossProduct(vector1,vector2) :
a,b,c = vector1
d,e,f = vector2
vector3 = (b*f-c*e , -a*f+c*d , a*e-b*d)
return vector3
def fixRect(rectList) :
Ax,Ay,Bx,By,Cx,Cy,Dx,Dy = rectList[:]
v12 = (Bx-Ax,By-Ay,0)
v13 = (Cx-Ax,Cy-Ay,0)
v14 = (Dx-Ax,Dy-Ay,0)
z1 = crossProduct(v13,v12)[2]
z2 = crossProduct(v13,v14)[2]
if z1*z2 < 0 : # if two z values have different sign, they are in order
return [Ax,Ay,Bx,By,Cx,Cy,Dx,Dy]
# else swap 2 and 3
Ax,Ay,Cx,Cy,Bx,By,Dx,Dy = rectList[:]
# repeat
v12 = (Bx-Ax,By-Ay,0)
v13 = (Cx-Ax,Cy-Ay,0)
v14 = (Dx-Ax,Dy-Ay,0)
z1 = crossProduct(v13,v12)[2]
z2 = crossProduct(v13,v14)[2]
if z1*z2 < 0 : # if two z values have different sign, they are in order
return [Ax,Ay,Bx,By,Cx,Cy,Dx,Dy]
# else swap 3 and 4
Ax,Ay,Bx,By,Dx,Dy,Cx,Cy = rectList[:]
# repeat
v12 = (Bx-Ax,By-Ay,0)
v13 = (Cx-Ax,Cy-Ay,0)
v14 = (Dx-Ax,Dy-Ay,0)
z1 = crossProduct(v13,v12)[2]
z2 = crossProduct(v13,v14)[2]
if z1*z2 < 0 : # if two z values have different sign, they are in order
return [Ax,Ay,Bx,By,Cx,Cy,Dx,Dy]
else: raise Exception("Couldn't fix the rectangle")
def叉积(矢量1、矢量2):
a、 b,c=vector1
d、 e,f=vector2
向量3=(b*f-c*e,-a*f+c*d,a*e-b*d)
返回向量3
def fixRect(rectList):
Ax,Ay,Bx,By,Cx,Cy,Dx,Dy=rectList[:]
v12=(Bx Ax,按日期,0)
v13=(Cx Ax,Cy Ay,0)
v14=(Dx-Ax,Dy-Ay,0)
z1=叉积(v13,v12)[2]
z2=叉积(v13,v14)[2]
如果z1*z2<0:#如果两个z值具有不同的符号,则它们是有序的
返回[Ax,Ay,Bx,By,Cx,Cy,Dx,Dy]
#否则交换2和3
Ax,Ay,Cx,Cy,Bx,By,Dx,Dy=rectList[:]
#重复
v12=(Bx Ax,按日期,0)
v13=(Cx Ax,Cy Ay,0)
v14=(Dx-Ax,Dy-Ay,0)
z1=叉积(v13,v12)[2]
z2=叉积(v13,v14)[2]
如果z1*z2<0:#如果两个z值具有不同的符号,则它们是有序的
返回[Ax,Ay,Bx,By,Cx,Cy,Dx,Dy]
#否则交换3和4
Ax,Ay,Bx,By,Dx,Dy,Cx,Cy=rectList[:]
#重复
v12=(Bx Ax,按日期,0)
v13=(Cx Ax,Cy Ay,0)
v14=(Dx-Ax,Dy-Ay,0)
z1=叉积(v13,v12)[2]
z2=叉积(v13,v14)[2]
如果z1*z2<0:#如果两个z值具有不同的符号,则它们是有序的
返回[Ax,Ay,Bx,By,Cx,Cy,Dx,Dy]
else:引发异常(“无法修复矩形”)
制作一个从点1到点2的向量
从点1到点3做一个向量
从点1到点4做一个向量 计算向量1->3和1->2的叉积的z分量 计算向量1->3和1->4的叉积的z分量 如果这两个z有不同的符号(一个是负的,另一个是正的),你就有了你的观点
如果顺序不正确,请重复以上所有步骤,首先交换第3点和第2点。如果这还不够,那么交换原始点列表/点阵列中的点3和点4。从点1到点2创建一个向量
从点1到点3做一个向量
从点1到点4做一个向量 计算向量1->3和1->2的叉积的z分量 计算向量1->3和1->4的叉积的z分量 如果这两个z有不同的符号(一个是负的,另一个是正的),你就有了你的观点
如果顺序不正确,请重复以上所有步骤,首先交换第3点和第2点。如果这还不够,那么交换原始点列表/点阵列中的点3和点4。我知道这有点像僵尸问题,但我找不到相关的新问题。所以我会把这篇文章发出去,以防对别人有所帮助 这是我用过的一个算法。它依赖于以下假设:
- 它是一个正方形/矩形:4个顶点,边彼此成90度角
- 顶点已按顺序排列(顺时针或逆时针)
- 将其旋转R,使-45
将numpy导入为np
def排序直接(vec):
#从左上角开始,按顺时针顺序返回vec
normd=vec-np.平均值(vec,轴=0)#相对于质心的顶点
tl_idx=np.argmax(np.dot(normd,np.array([-1,-1]))#左上顶点的索引
顺时针=np.交叉(向量[(tl_idx+1)%4]-向量[tl_idx],
vec[tl_idx]-vec[tl_idx-1])>0
如果为顺时针方向,则返回np.roll(矢量,-tl_idx,轴=0),否则返回np.roll(矢量,-1-tl_idx,轴=0)[:-1]
我知道这有点像僵尸问题,但我找不到相关的新问题。所以我会把这篇文章发出去,以防对别人有所帮助
这是我用过的一个算法。它依赖于以下假设:
- 它是一个正方形/矩形:4个顶点,边彼此成90度角
- 顶点已按顺序排列(顺时针或逆时针)
- 将其旋转R,使-45
将numpy导入为np
def排序直接(vec):
#从左上角开始,按顺时针顺序返回vec
normd=vec-np.平均值(vec,轴=0)#相对于质心的顶点
tl_idx=np.argmax(np.dot(normd,np.array([-1,-1]))#左上顶点的索引
顺时针=np.交叉(向量[(tl_idx+1)%4]-向量[tl_idx],
vec[tl_idx]-vec[tl_idx-1])>0
如果为顺时针方向,则返回np.roll(矢量,-tl_idx,轴=0),否则返回np.roll(矢量,-1-tl_idx,轴=0)[:-1]
您已经尝试了什么?为什么不发布一些代码呢?我可以通过比较对边的坡度来确定它们是否有序,但如果它们是随机的,我就无法将它们排序。你已经尝试过什么了?为什么不发布一些代码呢?我可以通过比较对边的坡度来确定它们是否有序,但如果它们是随机的,我就无法将它们排序。+1-x乘积的使用很好。OP没有说明在俯视平面的单位向量时,“正确”的顺序需要顺时针还是逆时针顺序。我想让他们按照逆时针、右手规则排序。@duffymo一旦你得到了两个顺序中的一个的分数,