Spaces:
Sleeping
Sleeping
File size: 3,855 Bytes
e0ef700 |
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 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
#!/usr/bin/env python3
"""Debug the angles from Rivin LP vs geometric realization."""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent))
import numpy as np
from ideal_poly_volume_toolkit.plantri_interface import find_plantri_executable
from ideal_poly_volume_toolkit.planar_utils import extract_faces_from_planar_embedding
from ideal_poly_volume_toolkit.rivin_delaunay import (
check_delaunay_realizability,
realize_angles_as_points,
compute_triangle_angle
)
import subprocess
def get_octahedron():
"""Get the octahedron triangulation (n=6, index=6)."""
plantri = find_plantri_executable()
args = [plantri, '-pc3', '-a', '6']
result = subprocess.run(args, capture_output=True, text=True)
triangulations = []
for line in result.stdout.split('\n'):
line = line.strip()
if not line or line.startswith('>'):
continue
parts = line.split(maxsplit=1)
if len(parts) != 2:
continue
n = int(parts[0])
adj_str = parts[1]
adj = {}
for v_idx, neighbor_str in enumerate(adj_str.split(',')):
neighbors = [ord(c) - ord('a') for c in neighbor_str]
adj[v_idx] = neighbors
closed_tri = extract_faces_from_planar_embedding(n, adj)
planar_tri = [tri for tri in closed_tri if 0 not in tri]
if planar_tri:
triangulations.append(planar_tri)
return triangulations[6] # The octahedron
if __name__ == '__main__':
triangles = get_octahedron()
print("="*70)
print("OCTAHEDRON ANGLE ANALYSIS")
print("="*70)
print(f"\nTriangles: {triangles}")
# Check strict realizability
result = check_delaunay_realizability(triangles, verbose=True, strict=True)
print(f"\n{'='*70}")
print("LP SOLUTION ANGLES")
print(f"{'='*70}")
angles = result['angles']
n_triangles = len(triangles)
target_angles = angles.reshape((n_triangles, 3))
for i, tri in enumerate(triangles):
print(f"\nTriangle {i}: {tri}")
print(f" Angles (rad): {target_angles[i]}")
print(f" Angles (deg): {np.degrees(target_angles[i])}")
print(f" Sum: {target_angles[i].sum():.6f} rad (π = {np.pi:.6f})")
# Try realization
print(f"\n{'='*70}")
print("GEOMETRIC REALIZATION")
print(f"{'='*70}")
realization = realize_angles_as_points(triangles, target_angles, verbose=True)
if realization['success']:
print(f"\n{'='*70}")
print("REALIZED ANGLES")
print(f"{'='*70}")
points = realization['points']
vertex_list = realization['vertex_list']
vertex_to_idx = {v: i for i, v in enumerate(vertex_list)}
print(f"\nPoint positions:")
for i, v in enumerate(vertex_list):
print(f" v{v}: ({points[i, 0]:8.5f}, {points[i, 1]:8.5f})")
print(f"\nActual angles achieved:")
for i, tri in enumerate(triangles):
v0, v1, v2 = tri
p0 = points[vertex_to_idx[v0]]
p1 = points[vertex_to_idx[v1]]
p2 = points[vertex_to_idx[v2]]
angle0 = compute_triangle_angle(p0, p1, p2)
angle1 = compute_triangle_angle(p1, p2, p0)
angle2 = compute_triangle_angle(p2, p0, p1)
print(f"\nTriangle {i}: {tri}")
print(f" Target angles (rad): {target_angles[i]}")
print(f" Target angles (deg): {np.degrees(target_angles[i])}")
print(f" Actual angles (rad): [{angle0:.6f}, {angle1:.6f}, {angle2:.6f}]")
print(f" Actual angles (deg): {np.degrees([angle0, angle1, angle2])}")
print(f" Error (rad): {target_angles[i] - np.array([angle0, angle1, angle2])}")
print(f" Error (deg): {np.degrees(target_angles[i] - np.array([angle0, angle1, angle2]))}")
|