-
Notifications
You must be signed in to change notification settings - Fork 1
/
squarish.py
84 lines (62 loc) · 2 KB
/
squarish.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import math
def distance(p1, p2):
result = math.sqrt( (p2[0] - p1[0])**2 + (p2[1] - p1[1])**2 )
return result
def distances(points):
p1, p2, p3, p4 = points
d1 = distance(p1, p2)
d2 = distance(p2, p3)
d3 = distance(p3, p4)
d4 = distance(p4, p1)
return [d1, d2, d3, d4]
def angles(points):
sides = distances(points)
angles = []
for i in range(4):
a = sides[i]
b = sides[i-3]
# Calculate hypotenuse
h = distance(points[i],points[i-2])
# Calculate angle of corner
try:
angle = math.acos( (a**2 + b**2 - h**2) / (2 * a * b) ) / 6.28 * 360
angles.append(angle)
except ZeroDivisionError:
return False
return angles
def squarish(points, threshold=.6):
#points = map(tuple, points)
# Are all side lengths about the same?
d = distances(points)
shortest = float(min(d))
longest = float(max(d))
distance_ratio = shortest / longest
distances_are_close_enough = False
if distance_ratio >= threshold:
distances_are_close_enough = True
# Are all angles about the same?
a = angles(points)
if a == False:
return False
smallest = float(min(a))
largest = float(max(a))
angle_ratio = smallest / largest
angles_are_close_enough = False
if angle_ratio >= threshold:
angles_are_close_enough = True
#return distances_are_close_enough and angles_are_close_enough
return distances_are_close_enough
if __name__ == '__main__':
# Test a perfect square
points = ((0,1), (1,1), (1,0), (0,0))
print ("Distances: ", distances(points))
print ("Angles: ", angles(points))
print (squarish(points))
points = ((0+.5,1), (1+.1,1), (1,0), (0,0))
print()
print ("Distances: ", distances(points))
print ("Angles: ", angles(points))
print (squarish(points))
# More test cases:
# This used to cause a ZeroDivisionError
# [(139.0, 230.0), (139.0, 230.0), (111.0, 305.0), (111.0, 305.0)]