dyna3/impossolid/angle-distortion.py

60 lines
2.2 KiB
Python
Raw Normal View History

2025-09-29 16:31:36 -07:00
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 edges:
for v in 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))