59 lines
2.2 KiB
Python
59 lines
2.2 KiB
Python
import collections
|
|
import math
|
|
import sys
|
|
|
|
def read_edge_distortions(filename):
|
|
vertices = set()
|
|
distortions = {}
|
|
with open(filename, 'r') as edge_file:
|
|
while edge_line := edge_file.readline():
|
|
line_parts = edge_line.rstrip().split(': ')
|
|
endpoints = tuple(sorted(line_parts[0].split(', ')))
|
|
vertices.update(endpoints)
|
|
if len(line_parts) > 1:
|
|
distortions[endpoints] = float(line_parts[1])
|
|
else:
|
|
distortions[endpoints] = 0
|
|
return (vertices, distortions)
|
|
|
|
def find_triangles(vertices, edges):
|
|
triangles = []
|
|
for e in sorted(edges):
|
|
for v in sorted(vertices):
|
|
if e[1] < v:
|
|
if (e[0], v) in edges and (e[1], v) in edges:
|
|
triangles.append((e[0], e[1], v))
|
|
return triangles
|
|
|
|
# use the law of cosines to get the angle distortion
|
|
def angle_distortion(edge_distortions):
|
|
a, b, c = list(edge_distortions)
|
|
cos_angle_a = (1 + 2*(b + c - a) + b*b + c*c - a*a) / (2*(1 + b)*(1 + c))
|
|
return math.degrees(math.acos(cos_angle_a)) - 60
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) <= 1:
|
|
print('Pass the path to the file that lists the edge distortions')
|
|
else:
|
|
vertices, distortions = read_edge_distortions(sys.argv[1])
|
|
triangles = find_triangles(vertices, distortions.keys())
|
|
total_angle_distortion = 0
|
|
highest_angle_distortion = -math.inf
|
|
lowest_angle_distortion = math.inf
|
|
print('{} triangles\n'.format(len(triangles)))
|
|
for t in triangles:
|
|
print('Triangle {0}, {1}, {2}'.format(t[0], t[1], t[2]))
|
|
edge_distortions = collections.deque(
|
|
[distortions[(t[j], t[k])] for (j, k) in [(1, 2), (0, 2), (0, 1)]]
|
|
)
|
|
for k in range(3):
|
|
ang_distort = angle_distortion(edge_distortions)
|
|
total_angle_distortion += abs(ang_distort)
|
|
highest_angle_distortion = max(highest_angle_distortion, ang_distort)
|
|
lowest_angle_distortion = min(lowest_angle_distortion, ang_distort)
|
|
print(' {0}: {1}°'.format(t[k], ang_distort))
|
|
edge_distortions.rotate()
|
|
print()
|
|
print('Total angle distortion: {}°'.format(total_angle_distortion))
|
|
print('Highest angle distortion: {}°'.format(highest_angle_distortion))
|
|
print('Lowest angle distortion: {}°'.format(lowest_angle_distortion))
|