code wiki / _hdl_build / nx_sqprim_gate.nx
nx_sqprim_gate.nx source
↩ module page · 123 lines · 6140 B
1// nx_sqprim_gate.nx -- teeth for the SUPERQUADRIC primitive in nx_bodyatlas (2026-07-27).
2//
3// ★WHY: every part in the atlas was an axis-aligned ELLIPSOID. The literature calls that the EARLY
4// formulation for anatomy; the modern primitive is the GENERALIZED CYLINDER, of which superquadrics are
5// the superelliptical-cross-section subset (6 pose + 3 size + 2 SHAPE parameters). An ellipsoid cannot
6// express a vertebral body (boxy) or a tapering muscle belly (pinched) -- not badly, AT ALL, because it
7// has no shape degree of freedom. This gate proves the exponent is a real DOF and not a relabel.
8//
9// ★THE ORDERING IS THE POINT AND IT IS MEASURED, NOT ASSERTED: for a fixed radius the enclosed volume
10// must be strictly increasing in the exponent -- a diamond is inside an ellipsoid is inside a rounded
11// box -- because higher exponents push the surface out toward the corners of the bounding box.
12// expect_exit: 0 license_tier: ORIGINAL No hw writes (Rule 26).
13import "nx_bodyatlas.nx"
14import "nx_gate_verdict.nx"
15
16const SQ_ONE: i64 = 1024
17const SQ_G: i64 = 24 // grid half-extent for the volume count
18const SQ_R: i64 = 1000 // part radius used by the fixtures
19
20// count lattice points inside the unit superquadric of exponent e, by direct norm evaluation
21func sq_volume(e: i64) -> i64 {
22 var n: i64 = 0
23 var ix: i64 = 0 - SQ_G
24 while ix <= SQ_G {
25 var iy: i64 = 0 - SQ_G
26 while iy <= SQ_G {
27 var iz: i64 = 0 - SQ_G
28 while iz <= SQ_G {
29 let ax: i64 = ba_iabs(ix) * SQ_ONE / SQ_G
30 let ay: i64 = ba_iabs(iy) * SQ_ONE / SQ_G
31 let az: i64 = ba_iabs(iz) * SQ_ONE / SQ_G
32 if ba_sq_norm(ax, ay, az, e) <= SQ_ONE { n = n + 1 }
33 iz = iz + 1
34 }
35 iy = iy + 1
36 }
37 ix = ix + 1
38 }
39 return n
40}
41
42func main() -> i64 {
43 let ctr: *i64 = gv_ctr()
44 gv_head("nx_sqprim selftest -- superquadric shape exponent, the DOF an ellipsoid does not have" as *u8)
45
46 // ★T1 ADDITIVE: e=2 must evaluate the ellipsoid expression EXACTLY. Checked against a direct
47 // recomputation of the original formula, not against a remembered number.
48 var t1: i64 = 1
49 var k: i64 = 0
50 while k < 40 {
51 let ax: i64 = k * 137 % 3000
52 let ay: i64 = k * 211 % 3000
53 let az: i64 = k * 89 % 3000
54 let want: i64 = ba_isqrt(ax*ax + ay*ay + az*az)
55 if ba_sq_norm(ax, ay, az, BA_SQ_ELL) != want { t1 = 0 }
56 k = k + 1
57 }
58 gv_check("T1 ADDITIVE: e=2 reproduces the ellipsoid norm EXACTLY over 40 sample points" as *u8, t1, ctr)
59
60 // ★T2 the surface is at unity for every exponent -- a point on an axis at radius 1 is ON the surface,
61 // so the exponent changes the CORNERS and never the semi-axes. If this failed the exponent would be
62 // silently rescaling the part rather than reshaping it.
63 var t2: i64 = 1
64 if ba_sq_norm(SQ_ONE, 0, 0, 1) != SQ_ONE { t2 = 0 }
65 if ba_sq_norm(SQ_ONE, 0, 0, 2) != SQ_ONE { t2 = 0 }
66 if ba_iabs(ba_sq_norm(SQ_ONE, 0, 0, 4) - SQ_ONE) > 2 { t2 = 0 }
67 if ba_iabs(ba_sq_norm(0, SQ_ONE, 0, 8) - SQ_ONE) > 2 { t2 = 0 }
68 gv_check("T2 the semi-axes are FIXED at every exponent -- shape changes, size does not" as *u8, t2, ctr)
69
70 // ★★T3 THE MEASURED ORDERING. Enclosed volume must be strictly increasing in the exponent.
71 let v1: i64 = sq_volume(1)
72 let v2: i64 = sq_volume(2)
73 let v4: i64 = sq_volume(4)
74 let v8: i64 = sq_volume(8)
75 gv_puts(" lattice volume: e1=" as *u8); gv_num(v1)
76 gv_puts(" e2=" as *u8); gv_num(v2)
77 gv_puts(" e4=" as *u8); gv_num(v4)
78 gv_puts(" e8=" as *u8); gv_num(v8); gv_puts("\n" as *u8)
79 var t3: i64 = 0
80 if v1 < v2 { if v2 < v4 { if v4 < v8 { t3 = 1 } } }
81 gv_check("T3 MEASURED: volume strictly increases e1 < e2 < e4 < e8 (diamond..box)" as *u8, t3, ctr)
82
83 // ★T4 ANTI-VACUITY the other way: the exponent must make a LARGE difference, not a rounding one.
84 // A vertebral body is visibly not an egg; if e=4 were within a few percent of e=2 the DOF would be
85 // decorative. Demand e=4 enclose at least a fifth more lattice points than e=2.
86 var t4: i64 = 0
87 if v4 > v2 + v2/5 { t4 = 1 }
88 gv_check("T4 the exponent is a LARGE effect, not a rounding artifact (e4 > 1.2x e2)" as *u8, t4, ctr)
89
90 // ★T5 the corner test, which is what "boxy" actually means: the body diagonal at 0.8 of the radius
91 // is OUTSIDE an ellipsoid and INSIDE a rounded box.
92 let c: i64 = SQ_ONE * 8 / 10
93 var t5: i64 = 0
94 if ba_sq_norm(c, c, c, 2) > SQ_ONE { if ba_sq_norm(c, c, c, 8) <= SQ_ONE { t5 = 1 } }
95 gv_check("T5 CORNERS: a body-diagonal point is outside the ellipsoid and inside the box" as *u8, t5, ctr)
96
97 // ★T6 and the pinched direction: the same point must be outside the DIAMOND too, further out than
98 // the ellipsoid -- so e=1 tapers rather than bulges.
99 var t6: i64 = 0
100 if ba_sq_norm(c, c, c, 1) > ba_sq_norm(c, c, c, 2) { t6 = 1 }
101 gv_check("T6 e=1 is PINCHED: the diagonal sits further outside than for the ellipsoid" as *u8, t6, ctr)
102
103 // ★T7 the atlas still builds and every part defaults to the ellipsoid, so the 119-part being is
104 // unchanged until a part deliberately asks to be otherwise.
105 atlas_build(0)
106 var t7: i64 = 1
107 var p: i64 = 0
108 let np: i64 = atlas_part_count()
109 while p < np { if ba_part_shape(p) != BA_SQ_ELL { t7 = 0 } p = p + 1 }
110 var t7b: i64 = 0
111 if np > 100 { if t7 == 1 { t7b = 1 } }
112 gv_puts(" atlas parts=" as *u8); gv_num(np); gv_puts(" all defaulting to e=2\n" as *u8)
113 gv_check("T7 the whole atlas still defaults to the ellipsoid -- nothing changed under it" as *u8, t7b, ctr)
114
115 // ★T8 and the setter actually takes, so the DOF is reachable from the part table
116 ba_shape(4)
117 var t8: i64 = 0
118 if ba_part_shape(np-1) == 4 { t8 = 1 }
119 gv_check("T8 ba_shape sets the exponent on the part just added" as *u8, t8, ctr)
120
121 return gv_verdict("SQPRIM-GATE" as *u8, ctr,
122 "superquadric shape exponent: additive at e=2, measured volume ordering, corners proven" as *u8)
123}