idealpolyhedra / examples /test_realizability_modes.py
igriv's picture
Add HuggingFace Spaces support
e0ef700
#!/usr/bin/env python3
"""
Test the different realizability modes: standard, strict, and Andreev.
"""
import numpy as np
from scipy.spatial import Delaunay
import sys
sys.path.insert(0, '/home/igor/devel/ideal_poly_volume_toolkit')
from ideal_poly_volume_toolkit.rivin_delaunay import check_delaunay_realizability
def test_simple_triangulation():
"""Test a simple triangulation with all three modes."""
print("=" * 70)
print("TEST: Simple hexagon triangulation")
print("=" * 70)
# Create a simple hexagon triangulation
# 6 boundary vertices forming a regular hexagon + triangulation
points = np.array([
[np.cos(i * np.pi / 3), np.sin(i * np.pi / 3)]
for i in range(6)
])
tri = Delaunay(points)
triangles = [tuple(simplex) for simplex in tri.simplices]
print(f"\nTriangulation: {len(triangles)} triangles, {len(points)} vertices")
print(f"Triangles: {triangles}")
# Test standard mode
print("\n" + "-" * 70)
print("MODE 1: STANDARD (dihedral ≤ π)")
print("-" * 70)
result_standard = check_delaunay_realizability(triangles, verbose=True)
print(f"\n✓ Realizable: {result_standard['realizable']}")
if result_standard['realizable']:
print(f" Min angle: {result_standard['min_angle_radians']:.6f} rad = {np.degrees(result_standard['min_angle_radians']):.2f}°")
# Test strict mode
print("\n" + "-" * 70)
print("MODE 2: STRICT (dihedral < π)")
print("-" * 70)
result_strict = check_delaunay_realizability(triangles, verbose=True, strict=True)
print(f"\n✓ Realizable (strict): {result_strict['realizable']}")
if result_strict['realizable']:
print(f" Min angle: {result_strict['min_angle_radians']:.6f} rad = {np.degrees(result_strict['min_angle_radians']):.2f}°")
print(f" Dihedral slack: {result_strict['slack_radians']:.6f} rad = {np.degrees(result_strict['slack_radians']):.2f}°")
print(f" Max dihedral: {result_strict['max_dihedral_radians']:.6f} rad = {np.degrees(result_strict['max_dihedral_radians']):.2f}°")
# Test Andreev mode
print("\n" + "-" * 70)
print("MODE 3: ANDREEV (dihedral ≤ π/2)")
print("-" * 70)
result_andreev = check_delaunay_realizability(triangles, verbose=True, andreev=True)
print(f"\n✓ Realizable (Andreev): {result_andreev['realizable']}")
if result_andreev['realizable']:
print(f" Min angle: {result_andreev['min_angle_radians']:.6f} rad = {np.degrees(result_andreev['min_angle_radians']):.2f}°")
print("\n" + "=" * 70)
print("SUMMARY")
print("=" * 70)
print(f"Standard realizable: {result_standard['realizable']}")
print(f"Strict realizable: {result_strict['realizable']}")
print(f"Andreev realizable: {result_andreev['realizable']}")
return result_standard, result_strict, result_andreev
def test_random_triangulation():
"""Test a random triangulation."""
print("\n\n" + "=" * 70)
print("TEST: Random triangulation (10 points)")
print("=" * 70)
np.random.seed(42)
points = np.random.rand(10, 2)
tri = Delaunay(points)
triangles = [tuple(simplex) for simplex in tri.simplices]
print(f"\nTriangulation: {len(triangles)} triangles, {len(points)} vertices")
# Quick tests without verbose
result_standard = check_delaunay_realizability(triangles, verbose=False)
result_strict = check_delaunay_realizability(triangles, verbose=False, strict=True)
result_andreev = check_delaunay_realizability(triangles, verbose=False, andreev=True)
print("\n" + "=" * 70)
print("RESULTS")
print("=" * 70)
print(f"Standard realizable: {result_standard['realizable']}")
if result_standard['realizable']:
print(f" Min angle: {np.degrees(result_standard['min_angle_radians']):.2f}°")
print(f"\nStrict realizable: {result_strict['realizable']}")
if result_strict['realizable']:
print(f" Min angle: {np.degrees(result_strict['min_angle_radians']):.2f}°")
print(f" Dihedral slack: {np.degrees(result_strict['slack_radians']):.2f}°")
print(f" Max dihedral: {np.degrees(result_strict['max_dihedral_radians']):.2f}° (< 180°)")
print(f"\nAndreev realizable: {result_andreev['realizable']}")
if result_andreev['realizable']:
print(f" Min angle: {np.degrees(result_andreev['min_angle_radians']):.2f}°")
return result_standard, result_strict, result_andreev
def test_octahedron():
"""Test octahedron (known to be realizable)."""
print("\n\n" + "=" * 70)
print("TEST: Octahedron (6 vertices, remove one -> square pyramid)")
print("=" * 70)
# Octahedron vertices on sphere
points_3d = np.array([
[1, 0, 0],
[-1, 0, 0],
[0, 1, 0],
[0, -1, 0],
[0, 0, 1],
])
# Project to 2D for Delaunay (we removed vertex [0, 0, -1])
points = points_3d[:, :2]
tri = Delaunay(points)
triangles = [tuple(simplex) for simplex in tri.simplices]
print(f"\nTriangulation: {len(triangles)} triangles, {len(points)} vertices")
# Test all modes
result_standard = check_delaunay_realizability(triangles, verbose=False)
result_strict = check_delaunay_realizability(triangles, verbose=False, strict=True)
result_andreev = check_delaunay_realizability(triangles, verbose=False, andreev=True)
print("\n" + "=" * 70)
print("RESULTS")
print("=" * 70)
print(f"Standard realizable: {result_standard['realizable']}")
print(f"Strict realizable: {result_strict['realizable']}")
print(f"Andreev realizable: {result_andreev['realizable']}")
if result_strict['realizable']:
print(f"\nStrict mode details:")
print(f" Dihedral slack: {np.degrees(result_strict['slack_radians']):.4f}°")
print(f" Max dihedral: {np.degrees(result_strict['max_dihedral_radians']):.4f}° (< 180°)")
return result_standard, result_strict, result_andreev
if __name__ == '__main__':
print("Testing Rivin Delaunay Realizability with different modes\n")
# Run tests
test_simple_triangulation()
test_random_triangulation()
test_octahedron()
print("\n\n" + "=" * 70)
print("ALL TESTS COMPLETE")
print("=" * 70)