我正在尝试在 python(2.7) 中编写一个函数。该函数将采用一个包含 8 个值的列表,这些值表示顶点的坐标。
(输入的形式是 [Ax,Ay,Bx,By,Cx,Cy,Dx,Dy] )
该函数将确定这些顶点是否被给出以形成一个有效的矩形。
如果不是,它会将它们按顺序排列并返回这些顶点的排序列表。起点或方向(是顺时针还是逆时针)并不重要。
让我说明我想要什么:
如果给定的输入在下面的链接中形成第二或第三个形状;该函数会将其转换为第一个。
http://i.stack.imgur.com/IsRqr.png
我可以使用哪种算法来做到这一点?
我使用了 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")