有四点作为元组;p1 = (2, 2), p2 = (2, 6), p3 = (6, 6) and p4 = (6, 2)。我希望这四个元组点通过4种不同类型的函数: isSquare(p1,p2,p3,p4),isRectangle(p1,p2,p3,p4),isParallelogram(p1,p2,p3,p4)和isRhombus(p1,p2,p4,)检查它的正方形、矩形、平行四边形还是菱形。
发布于 2022-06-05 17:43:49
编辑尝试2:相反,计算点之间的向量,找出唯一向量的数目和在同一点上相遇的向量之间的角度,以确定所需的四种形状中的哪一种(注意,这种方法要求按所连接的顺序排列点):
import numpy as np
def quadrilateral2(*args):
if len(args) != 4:
return 'Not a quadrilateral'
args = np.array(args)
vectors = np.array([args[i-1]-j for i, j in enumerate(args)])
unique_vectors = np.unique(np.round(np.abs(vectors), 6), axis=0) #Round to avoid numerical errors: can change the number of digits to round to
if len(unique_vectors) != 2:
return 'Not a square, rectangle, rhombus or parallelogram'
norms = [np.linalg.norm(i) for i in vectors]
norm_vectors = [i/j for i, j in zip(vectors, norms)]
unique_norms = set(round(i, 6) for i in norms) # Again, round for numerical errors
angles = [np.arccos(np.dot(norm_vectors[i-1], j)) for i, j in enumerate(norm_vectors)]
if all(i == np.pi/2 for i in angles):
if len(unique_norms) == 1:
return 'Square'
if len(unique_norms) == 2:
return 'Rectangle'
elif len(set(round(i, 6) for i in angles)) == 2: #Again, round for numerical errors
if len(unique_norms) == 1:
return 'Rhombus'
if len(unique_norms) == 2:
return 'Parallelogram'
else:
return 'Not a square, rectangle, rhombus or parallelogram'与以前的测试和作为注释的测试:
square = [(2, 2), (2, 4), (4,4), (4, 2)]
rectangle = [(2, 2), (2,8), (4, 8), (4, 2)]
rhombus = [(0, 0), (np.sqrt(8), 0), (2+np.sqrt(8), 2), (2, 2)]
parallelogram = [(2,2), (5, 2), (6,4), (3,4)]
print(quadrilateral2(*square))
print(quadrilateral2(*rectangle))
print(quadrilateral2(*rhombus))
print(quadrilateral2(*parallelogram))
print(quadrilateral2(*[[2, -3], [6, 5], [-2, 1], [-6, -7]]))
print(quadrilateral2(*[(0, 0), (0, -5), (3,2.5), (3, -2.5)]))
print(quadrilateral2(*[(0, 2), (0, -2), (-1,0), (1, 0)]))输出:
Square
Rectangle
Rhombus
Parallelogram
Rhombus
Not a square, rectangle, rhombus or parallelogram
Not a square, rectangle, rhombus or parallelogram免责声明:不适用于任何输入,但我认为如果输入保证为正方形、矩形、平行四边形或菱形,则可以工作。好的,我认为这很有效,但我还没有对它进行太多的测试。本质上,您需要计算所有给定点之间的唯一距离和唯一角度,然后使用所需形状的知识从这些距离和角度(如果有的话)确定形状:
import itertools
import numpy as np
def quadrilateral(*args):
tol = 1e-4
if not len(args) == 4:
return 'Not a quadrilateral'
#Calculate all permutations of the coordinates
permutations = np.array(list(itertools.permutations(args, r=2)))
#Calculate all distances
distances = np.array(list(np.sqrt(sum((i[0]-i[1])**2)) for i in permutations))
#Choose unique distances within a tolerance tol
distances = distances[~(np.triu(np.abs(distances[:,None] - distances) <= tol,1)).any(0)]
#Calculate all absolute angles
angles = np.array(list(abs(np.arctan2(*(i[0]-i[1])[::-1])) for i in permutations))
#Choose unique angles within a tolerance tol
angles = sorted(angles[~(np.triu(np.abs(angles[:,None] - angles) <= tol,1)).any(0)])
if len(distances) == 2 and all(np.pi*i/4 == j for i, j in enumerate(angles)):
return "It's a square"
elif len(distances) == 3:
if len(angles) == 5:
return "It's a rectangle"
elif len(angles) == 8:
return "It's a rhombus"
else:
return 'Not a square, rectangle, rhombus or parallelogram'
elif len(distances) == 4 and len(angles) == 8:
return "It's a parallelogram"
else:
return 'Not a square, rectangle, rhombus or parallelogram'简单测试用例:
square = [(2, 2), (2, 4), (4,2), (4, 4)]
rectangle = [(2, 2), (4, 2), (2,8), (4, 8)]
rhombus = [(0, 0), (2, 2), (np.sqrt(8), 0), (2+np.sqrt(8), 2)]
parallelogram = [(2,2), (3,4), (5, 2), (6,4)]
print(quadrilateral(*square))
print(quadrilateral(*rectangle))
print(quadrilateral(*rhombus))
print(quadrilateral(*parallelogram))输出:
It's a square
It's a rectangle
It's a rhombus
It's a parallelogramhttps://stackoverflow.com/questions/72509103
复制相似问题