graph TD A["Polygon types"] --> B["General polygon"] A --> C["Rectilinear polygon"] B --> D["Any-angle edges"] C --> E["Only H/V edges"] C --> F["90 and 270 degree corners"] classDef root fill:#88c0d0,stroke:#5e81ac,stroke-width:3px,color:#2e3440; classDef good fill:#a3be8c,stroke:#2e7d32,stroke-width:3px,color:#2e3440; classDef neutral fill:#e5e9f0,stroke:#4c566a,stroke-width:2px,color:#2e3440; class A root; class C,E,F good; class B,D neutral;
Same U-shape: 8 full vertices β 4 stored points S0 (0,0) S1 (3,3) S2 (2,1) S3 (1,3) I0 (3,0) I1 (2,3) I2 (1,1) I3 (0,3) stored (even-index) implicit (x-first) cut functions receive only the 4 stored points 2 points = rectangle 3 points = L-shape
graph LR A["Full vertex list\n8 points"] --> B["Remove collinear"] B --> C["Rotate:\nfirst edge horizontal"] C --> D["Take every other\nvertex"] D --> E["Even-index\n4 stored points"] E --> F["x-first\nreconstruct"] F --> G["Full boundary"] classDef input fill:#88c0d0,stroke:#5e81ac,stroke-width:3px,color:#2e3440; classDef step fill:#ebcb8b,stroke:#d08770,stroke-width:3px,color:#2e3440; classDef out fill:#a3be8c,stroke:#2e7d32,stroke-width:3px,color:#2e3440; class A input; class B,C,D step; class E,F,G out;
Between two stored points: move x first, then y x-first β S0 (x0,y0) S1 (x1,y1) implicit (x1,y0) same shape as the original full list y-first β S0 S1 (x0,y1) different polygon do not do this
Pieces are already canonical even-index polygons 2 stored points rectangle β opposite corners 3 stored points L-shape / orthogonally convex β
graph LR A["Full polygon"] --> B["Canonical even-index"] B --> C["Cut functions"] C --> D["Convex pieces"] D --> E["Pieces are even-index again"] classDef good fill:#a3be8c,stroke:#2e7d32,stroke-width:3px,color:#2e3440; classDef step fill:#88c0d0,stroke:#5e81ac,stroke-width:3px,color:#2e3440; class A,B,C,D,E step; class E good;
graph LR I["Issue 7\n8-point list"] --> Q{"Canonical\neven-index?"} Q -->|No| N["Full vertex list\nconsecutive points share axes"] N --> C["Close issue 7\nrepresentation problem"] Q -->|Yes| T["4-point U\n(0,0),(3,3),(2,1),(1,3)"] T --> P["2 convex pieces\nβ works"] classDef bad fill:#f8bbd0,stroke:#bf616a,stroke-width:3px,color:#2e3440; classDef good fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px,color:#2e3440; classDef warn fill:#ffe0b2,stroke:#d08770,stroke-width:3px,color:#2e3440; class N,C bad; class T,P good; class Q warn;
12-point even-index fixture: 3 convex pieces piece 0 area 1 piece 1 area 10 piece 2 area 9 split (2,3)-(1,2) no new point piece 1 piece 2 piece 0 original boundary (2,2) is implicit in piece 0; neither piece stores (2,2).
graph LR A["Issue 7\nrepresentation"] --> B["Canonical even-index\ndocumented"] B --> C["Issue 8\nzero-area piece"] C --> D["Remove filter\nraw pieces visible"] D --> E["Standalone C++\noriginal scan"] E --> F["Degenerate 2-node split\nno new point"] F --> G["Python parity"] G --> H["Next: Rust cut\nimplementation"] classDef good fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px,color:#2e3440; classDef step fill:#88c0d0,stroke:#5e81ac,stroke-width:3px,color:#2e3440; classDef next fill:#ffe0b2,stroke:#d08770,stroke-width:3px,color:#2e3440; class A,B,C,D,E,F,G step; class H next;