nx_supports_test.nx source
↩ module page · 89 lines · 3666 B
1// nx_supports_test.nx -- overhang detection on hand-built layer
2// pairs with closed-form expected counts.
3//
4// Test polygons (CCW unit squares + variants):
5// sq1 = unit square (0,0)-(Q14,Q14)
6// sq_big = bigger square (-Q14,-Q14)-(2*Q14,2*Q14) -- "mushroom"
7// on top of unit square
8// sq_inside = smaller (Q14/4, Q14/4)-(3*Q14/4, 3*Q14/4) -- entirely
9// within sq1 (supported)
10//
11// Closed-form invariants:
12// (a) First layer (prev=NULL): no overhang reported regardless of
13// cur polygon.
14// (b) Stacked same-size squares: 0 overhang (cur completely
15// inside prev expanded by any positive tolerance).
16// (c) Larger square on smaller: all 4 corners of cur are outside
17// prev's envelope -> 4 overhang points.
18// (d) Smaller square inside larger: 0 overhang.
19// (e) Bad input (cur n_verts < 3): BAD_INPUT verdict.
20// (f) NULL out param: BAD_INPUT verdict.
21// (g) Overhang tolerance 0 still works (uses prev as envelope
22// directly, no offset).
23//
24// expect_exit: 0
25// license_tier: ORIGINAL
26
27import "nx_syscalls.nx"
28import "nx_polygon.nx"
29import "nx_supports.nx"
30
31const Q14: i64 = 16384
32
33func main() -> i64 {
34 let sq1: *NxPolygon = nx_polygon_make_square(0, 0, Q14, Q14)
35 let sq_big: *NxPolygon = nx_polygon_make_square(-Q14, -Q14,
36 2 * Q14, 2 * Q14)
37 let sq_inside: *NxPolygon = nx_polygon_make_square(Q14 / 4, Q14 / 4,
38 (Q14 * 3) / 4,
39 (Q14 * 3) / 4)
40
41 // --- (a) First layer (prev=NULL) ---
42 let sp1: *NxSupportPoints = nx_supports_new(64)
43 let v1: i64 = nx_supports_layer_overhang(0 as *NxPolygon, sq1,
44 Q14 / 5, sp1)
45 if v1 != NX_SUPPORTS_OK { return 10 }
46 if sp1.n != 0 { return 11 }
47
48 // --- (b) Stacked same-size square ---
49 let sp2: *NxSupportPoints = nx_supports_new(64)
50 let v2: i64 = nx_supports_layer_overhang(sq1, sq1, Q14 / 5, sp2)
51 if v2 != NX_SUPPORTS_OK { return 20 }
52 if sp2.n != 0 { return 21 }
53
54 // --- (c) Bigger square on top of smaller: 4 overhang corners ---
55 let sp3: *NxSupportPoints = nx_supports_new(64)
56 let v3: i64 = nx_supports_layer_overhang(sq1, sq_big,
57 Q14 / 5, sp3)
58 if v3 != NX_SUPPORTS_OK { return 30 }
59 if sp3.n != 4 { return 31 }
60
61 // --- (d) Smaller inside larger ---
62 let sp4: *NxSupportPoints = nx_supports_new(64)
63 let v4: i64 = nx_supports_layer_overhang(sq1, sq_inside,
64 Q14 / 5, sp4)
65 if v4 != NX_SUPPORTS_OK { return 40 }
66 if sp4.n != 0 { return 41 }
67
68 // --- (e) Bad input (degenerate cur) ---
69 let degen: *NxPolygon = nx_polygon_alloc(4)
70 nx_polygon_add_vert(degen, 0, 0)
71 nx_polygon_add_vert(degen, 100, 0)
72 // Only 2 verts -- BAD_INPUT
73 let sp5: *NxSupportPoints = nx_supports_new(64)
74 let v5: i64 = nx_supports_layer_overhang(sq1, degen, Q14 / 5, sp5)
75 if v5 != NX_SUPPORTS_ERR_BAD_INPUT { return 50 }
76
77 // --- (f) NULL out param ---
78 let v6: i64 = nx_supports_layer_overhang(sq1, sq1, Q14 / 5,
79 0 as *NxSupportPoints)
80 if v6 != NX_SUPPORTS_ERR_BAD_INPUT { return 60 }
81
82 // --- (g) Tolerance 0: uses prev as envelope directly ---
83 let sp7: *NxSupportPoints = nx_supports_new(64)
84 let v7: i64 = nx_supports_layer_overhang(sq1, sq_inside, 0, sp7)
85 if v7 != NX_SUPPORTS_OK { return 70 }
86 if sp7.n != 0 { return 71 }
87
88 return 0
89}