File size: 3,511 Bytes
19abe39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
116
import numpy as np
import pytest
from env.graph import CreaseGraph, VERTEX_TOL


def test_init_boundary():
    g = CreaseGraph()
    assert len(g.vertices) == 4
    assert len(g.edges) == 4
    for eid, (v1, v2, assignment) in g.edges.items():
        assert assignment == 'B'
    assert g.interior_vertices() == []


def test_add_vertex_dedup():
    g = CreaseGraph()
    id1 = g.add_vertex(0.5, 0.5)
    id2 = g.add_vertex(0.5, 0.5)
    assert id1 == id2


def test_add_vertex_dedup_near():
    g = CreaseGraph()
    id1 = g.add_vertex(0.5, 0.5)
    id2 = g.add_vertex(0.5 + VERTEX_TOL * 0.5, 0.5)
    assert id1 == id2


def test_cyclic_order():
    g = CreaseGraph()
    center_id = g.add_vertex(0.5, 0.5)

    right_id = g.add_vertex(0.8, 0.5)   # 0 degrees
    top_id = g.add_vertex(0.5, 0.8)     # 90 degrees
    left_id = g.add_vertex(0.2, 0.5)    # 180 degrees
    bottom_id = g.add_vertex(0.5, 0.2)  # 270 degrees / -90 degrees

    e_right = g.add_edge(center_id, right_id, 'M')
    e_top = g.add_edge(center_id, top_id, 'M')
    e_left = g.add_edge(center_id, left_id, 'M')
    e_bottom = g.add_edge(center_id, bottom_id, 'M')

    cyclic = g.get_cyclic_edges(center_id)
    # Sorted by angle ascending: right(0), top(90), left(180), bottom(-90 → 270)
    # arctan2 for bottom gives -pi/2 which sorts before 0 in ascending order
    # So actual ascending order: bottom(-pi/2), right(0), top(pi/2), left(pi)
    assert len(cyclic) == 4

    def edge_angle(eid):
        ev1, ev2, _ = g.edges[eid]
        other_id = ev2 if ev1 == center_id else ev1
        ox, oy = g.vertices[other_id]
        cx, cy = g.vertices[center_id]
        return float(np.arctan2(oy - cy, ox - cx))

    angles = [edge_angle(eid) for eid in cyclic]
    assert angles == sorted(angles), "Edges should be sorted by ascending angle"

    assert e_right in cyclic
    assert e_top in cyclic
    assert e_left in cyclic
    assert e_bottom in cyclic

    # Verify specific order: bottom < right < top < left in angle space
    pos = {eid: i for i, eid in enumerate(cyclic)}
    assert pos[e_bottom] < pos[e_right] < pos[e_top] < pos[e_left]


def test_interior_vertices_empty():
    g = CreaseGraph()
    assert g.interior_vertices() == []


def test_interior_vertices_with_crease_intersection():
    g = CreaseGraph()
    center_id = g.add_vertex(0.5, 0.5)
    assert center_id in g.interior_vertices()


def test_split_edge():
    g = CreaseGraph()
    # Find the bottom boundary edge (0,0)-(1,0) which is edge 0: v0-v1
    original_edge_id = None
    for eid, (v1, v2, assignment) in g.edges.items():
        x1, y1 = g.vertices[v1]
        x2, y2 = g.vertices[v2]
        if {(x1, y1), (x2, y2)} == {(0.0, 0.0), (1.0, 0.0)}:
            original_edge_id = eid
            original_v1 = v1
            original_v2 = v2
            break

    assert original_edge_id is not None

    mid_id = g.add_vertex(0.5, 0.0)
    eid1, eid2 = g.split_edge(original_edge_id, mid_id)

    assert original_edge_id not in g.edges

    assert eid1 in g.edges
    assert eid2 in g.edges

    _, _, a1 = g.edges[eid1]
    _, _, a2 = g.edges[eid2]
    assert a1 == 'B'
    assert a2 == 'B'

    def edge_vertex_set(eid):
        v1, v2, _ = g.edges[eid]
        return {v1, v2}

    assert mid_id in edge_vertex_set(eid1)
    assert mid_id in edge_vertex_set(eid2)
    assert original_v1 in edge_vertex_set(eid1) or original_v1 in edge_vertex_set(eid2)
    assert original_v2 in edge_vertex_set(eid1) or original_v2 in edge_vertex_set(eid2)