nx_canon_proportions.nx source
↩ module page · 195 lines · 10091 B
1// nx_canon_proportions.nx -- S-class anatomical canon as data table.
2//
3// Each entry is a 4-tuple (i64 array layout): numerator_axis_id,
4// denominator_axis_id, target_ratio_q10, tolerance_q10. Family ids
5// declare which classical source the ratio belongs to.
6//
7// Flat-array layout instead of struct-returning functions to avoid
8// the nxc2 codegen bug with struct-pointer returns.
9
10// nx_safety_envelope:
11// intended_use: AUTO_APPLIED -- primitive-specific tuning queued
12// sil_target: SIL1
13// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail]
14// verdict: NOT_YET_EVALUATED
15
16import "nx_syscalls.nx"
17import "nx_phi.nx"
18
19// Sealed axis ids — what we measure.
20const NX_AXIS_EYE_WIDTH: i64 = 1
21const NX_AXIS_EYE_TO_EYE: i64 = 2
22const NX_AXIS_PUPIL_TO_PUPIL: i64 = 3
23const NX_AXIS_PUPIL_TO_MOUTH: i64 = 4
24const NX_AXIS_MOUTH_WIDTH: i64 = 5
25const NX_AXIS_FACE_WIDTH: i64 = 6
26const NX_AXIS_FACE_HEIGHT: i64 = 7 // ~ 1 head
27const NX_AXIS_FOREHEAD_H: i64 = 8 // hairline to brow
28const NX_AXIS_MIDFACE_H: i64 = 9 // brow to nose-base
29const NX_AXIS_LOWERFACE_H: i64 = 10 // nose-base to chin
30const NX_AXIS_NECK_WIDTH: i64 = 11
31const NX_AXIS_SHOULDER_WIDTH: i64 = 12
32const NX_AXIS_BUST_WIDTH: i64 = 13 // chest width including breasts
33const NX_AXIS_WAIST_WIDTH: i64 = 14
34const NX_AXIS_HIP_WIDTH: i64 = 15
35const NX_AXIS_BREAST_DIAMETER: i64 = 16 // single breast outer-curve span
36const NX_AXIS_NIPPLE_TO_NIPPLE: i64 = 17
37const NX_AXIS_NAVEL_HEIGHT: i64 = 18 // floor to navel
38const NX_AXIS_TOTAL_HEIGHT: i64 = 19
39const NX_AXIS_FEMUR_LENGTH: i64 = 20
40const NX_AXIS_SHIN_LENGTH: i64 = 21
41const NX_AXIS_HAND_LENGTH: i64 = 22
42const NX_AXIS_FOOT_LENGTH: i64 = 23
43const NX_AXIS_ARM_SPAN: i64 = 24
44// Lower-body + intimate anatomy (added 2026-05-14).
45const NX_AXIS_THIGH_MID_WIDTH: i64 = 25 // single thigh thickness at mid-femur
46const NX_AXIS_THIGH_GAP_WIDTH: i64 = 26 // gap between inner thighs (legs together)
47const NX_AXIS_PERINEUM_LENGTH: i64 = 27 // fourchette → anal verge distance
48const NX_AXIS_VULVA_HEIGHT: i64 = 28 // top of mons → fourchette
49const NX_AXIS_VULVA_WIDTH: i64 = 29 // outer labia at widest
50const NX_AXIS_LABIA_PROTRUSION: i64 = 30 // signed Q10 of minora out beyond outer line
51const NX_AXIS_GLUTE_PROJECTION: i64 = 31 // ass forward depth from sacrum plane
52const NX_AXIS_HIP_TO_GLUTE_DROP: i64 = 32 // vertical from iliac crest to gluteal fold
53
54// Sealed canon families.
55const NX_FAMILY_PHI: i64 = 1 // golden ratio
56const NX_FAMILY_FIBONACCI: i64 = 2 // successive Fib ratios
57const NX_FAMILY_VITRUVIAN: i64 = 3 // Da Vinci canon
58const NX_FAMILY_LOOMIS: i64 = 4 // head-as-unit grid
59const NX_FAMILY_LINEAR: i64 = 5 // simple linear multiple
60
61// Canon entry layout: 5 i64 per entry.
62const NX_CANON_FIELD_NUM_AXIS: i64 = 0
63const NX_CANON_FIELD_DEN_AXIS: i64 = 1
64const NX_CANON_FIELD_TARGET_Q10: i64 = 2
65const NX_CANON_FIELD_TOL_Q10: i64 = 3
66const NX_CANON_FIELD_FAMILY: i64 = 4
67const NX_CANON_FIELDS: i64 = 5
68
69const NX_CANON_ENTRY_COUNT: i64 = 30
70
71// Tolerance presets (Q10).
72const NX_TOL_TIGHT: i64 = 51 // 5% — S-class only
73const NX_TOL_NORMAL: i64 = 102 // 10% — A-class acceptable
74const NX_TOL_LOOSE: i64 = 205 // 20% — natural variation
75
76// Linear ratios (target in Q10).
77const NX_R_HEAD_TO_EYE: i64 = 7168 // 7.0 — 1 face_height = 7 eye-widths
78const NX_R_FACE_W_TO_EYE: i64 = 5120 // 5.0 — face width = 5 eye-widths
79const NX_R_PUPIL_PAIR_EYE: i64 = 1024 // 1.0 — eye-to-eye = 1 eye-width
80const NX_R_MOUTH_TO_EYE: i64 = 2048 // 2.0 — mouth = 2 eye-widths
81const NX_R_SHOULDER_FACE_W: i64 = 3072 // 3.0 — shoulder = 3 face-widths (women)
82const NX_R_BREAST_HEAD: i64 = 716 // 0.7 — breast diameter ≈ 0.7 head
83const NX_R_KNEE_TO_HEAD: i64 = 2048 // 2.0 — femur ≈ 2 heads
84const NX_R_SHIN_TO_HEAD: i64 = 1536 // 1.5 — shin ≈ 1.5 heads
85const NX_R_TOTAL_TO_HEAD: i64 = 7680 // 7.5 — total ≈ 7.5 heads (women)
86const NX_R_HAND_TO_FACE_H: i64 = 1024 // 1.0 — hand ≈ 1 face-height
87const NX_R_FOOT_TO_FACE_H: i64 = 1024 // 1.0 — foot ≈ 1 face-height
88const NX_R_NECK_FACE_W: i64 = 512 // 0.5
89const NX_R_FACE_THIRDS: i64 = 1024 // 1.0 — forehead:midface = 1:1
90const NX_R_ARMSPAN_HEIGHT: i64 = 1024 // 1.0 — armspan ≈ height (Vitruvian)
91const NX_R_HIP_FACE_W: i64 = 1024 // 1.0 — hip width ≈ face width
92// Lower-body canon ratios.
93const NX_R_THIGH_HIP_W: i64 = 614 // 0.6 — mid-thigh ≈ 0.6 × hip width
94const NX_R_THIGH_GAP_HIP: i64 = 102 // 0.1 — modest gap ≈ 10% hip
95const NX_R_PERINEUM_FACE_W: i64 = 410 // 0.4 — perineum ≈ 0.4 face width (~2-3 cm)
96const NX_R_VULVA_H_FACE_W: i64 = 819 // 0.8 — vulva height ≈ 0.8 face width
97const NX_R_VULVA_W_FACE_W: i64 = 410 // 0.4 — vulva width ≈ 0.4 face width
98const NX_R_GLUTE_PROJ_HIP: i64 = 410 // 0.4 — glute projection ≈ 0.4 hip width
99
100func nx_canon_get(canon: *i64, idx: i64, field: i64) -> i64 {
101 return canon[idx * NX_CANON_FIELDS + field]
102}
103
104func nx_canon_set(canon: *i64, idx: i64, num: i64, den: i64,
105 target: i64, tol: i64, fam: i64) -> i64 {
106 canon[idx * NX_CANON_FIELDS + 0] = num
107 canon[idx * NX_CANON_FIELDS + 1] = den
108 canon[idx * NX_CANON_FIELDS + 2] = target
109 canon[idx * NX_CANON_FIELDS + 3] = tol
110 canon[idx * NX_CANON_FIELDS + 4] = fam
111 return 0
112}
113
114// Build the canonical S-class proportion table.
115// Caller allocates: sys_mmap(NX_CANON_ENTRY_COUNT * NX_CANON_FIELDS * 8 + 16)
116func nx_canon_build(canon: *i64) -> i64 {
117 // Face structure (Loomis + phi)
118 nx_canon_set(canon, 0, NX_AXIS_FACE_HEIGHT, NX_AXIS_EYE_WIDTH,
119 NX_R_HEAD_TO_EYE, NX_TOL_NORMAL, NX_FAMILY_LOOMIS)
120 nx_canon_set(canon, 1, NX_AXIS_FACE_WIDTH, NX_AXIS_EYE_WIDTH,
121 NX_R_FACE_W_TO_EYE, NX_TOL_NORMAL, NX_FAMILY_LOOMIS)
122 nx_canon_set(canon, 2, NX_AXIS_EYE_TO_EYE, NX_AXIS_EYE_WIDTH,
123 NX_R_PUPIL_PAIR_EYE, NX_TOL_NORMAL, NX_FAMILY_LOOMIS)
124 nx_canon_set(canon, 3, NX_AXIS_MOUTH_WIDTH, NX_AXIS_EYE_WIDTH,
125 NX_R_MOUTH_TO_EYE, NX_TOL_NORMAL, NX_FAMILY_LOOMIS)
126 nx_canon_set(canon, 4, NX_AXIS_FACE_HEIGHT, NX_AXIS_FACE_WIDTH,
127 NX_PHI_Q10, NX_TOL_NORMAL, NX_FAMILY_PHI)
128 nx_canon_set(canon, 5, NX_AXIS_PUPIL_TO_PUPIL, NX_AXIS_PUPIL_TO_MOUTH,
129 NX_PHI_Q10, NX_TOL_NORMAL, NX_FAMILY_PHI)
130 nx_canon_set(canon, 6, NX_AXIS_FOREHEAD_H, NX_AXIS_MIDFACE_H,
131 NX_R_FACE_THIRDS, NX_TOL_NORMAL, NX_FAMILY_LOOMIS)
132 nx_canon_set(canon, 7, NX_AXIS_MIDFACE_H, NX_AXIS_LOWERFACE_H,
133 NX_R_FACE_THIRDS, NX_TOL_NORMAL, NX_FAMILY_LOOMIS)
134 nx_canon_set(canon, 8, NX_AXIS_NECK_WIDTH, NX_AXIS_FACE_WIDTH,
135 NX_R_NECK_FACE_W, NX_TOL_LOOSE, NX_FAMILY_LINEAR)
136
137 // Body proportions (phi + Vitruvian)
138 nx_canon_set(canon, 9, NX_AXIS_SHOULDER_WIDTH, NX_AXIS_FACE_WIDTH,
139 NX_R_SHOULDER_FACE_W, NX_TOL_NORMAL, NX_FAMILY_LOOMIS)
140 nx_canon_set(canon, 10, NX_AXIS_BUST_WIDTH, NX_AXIS_WAIST_WIDTH,
141 NX_PHI_Q10, NX_TOL_NORMAL, NX_FAMILY_PHI) // hourglass
142 nx_canon_set(canon, 11, NX_AXIS_HIP_WIDTH, NX_AXIS_WAIST_WIDTH,
143 NX_PHI_Q10, NX_TOL_NORMAL, NX_FAMILY_PHI) // hourglass
144 nx_canon_set(canon, 12, NX_AXIS_SHOULDER_WIDTH, NX_AXIS_WAIST_WIDTH,
145 NX_PHI_Q10, NX_TOL_NORMAL, NX_FAMILY_PHI)
146 nx_canon_set(canon, 13, NX_AXIS_HIP_WIDTH, NX_AXIS_FACE_WIDTH,
147 NX_R_HIP_FACE_W, NX_TOL_NORMAL, NX_FAMILY_LINEAR)
148 nx_canon_set(canon, 14, NX_AXIS_BREAST_DIAMETER, NX_AXIS_FACE_HEIGHT,
149 NX_R_BREAST_HEAD, NX_TOL_LOOSE, NX_FAMILY_LINEAR)
150 nx_canon_set(canon, 15, NX_AXIS_NIPPLE_TO_NIPPLE, NX_AXIS_FACE_WIDTH,
151 NX_PHI_INV_Q10 + 391, NX_TOL_NORMAL, NX_FAMILY_PHI) // ~1.024
152
153 // Vitruvian total-height and navel
154 nx_canon_set(canon, 16, NX_AXIS_TOTAL_HEIGHT, NX_AXIS_NAVEL_HEIGHT,
155 NX_PHI_Q10, NX_TOL_NORMAL, NX_FAMILY_VITRUVIAN)
156 nx_canon_set(canon, 17, NX_AXIS_TOTAL_HEIGHT, NX_AXIS_FACE_HEIGHT,
157 NX_R_TOTAL_TO_HEAD, NX_TOL_NORMAL, NX_FAMILY_VITRUVIAN)
158 nx_canon_set(canon, 18, NX_AXIS_ARM_SPAN, NX_AXIS_TOTAL_HEIGHT,
159 NX_R_ARMSPAN_HEIGHT, NX_TOL_NORMAL, NX_FAMILY_VITRUVIAN)
160
161 // Limbs (Fibonacci/phi convergence)
162 nx_canon_set(canon, 19, NX_AXIS_FEMUR_LENGTH, NX_AXIS_FACE_HEIGHT,
163 NX_R_KNEE_TO_HEAD, NX_TOL_NORMAL, NX_FAMILY_LINEAR)
164 nx_canon_set(canon, 20, NX_AXIS_SHIN_LENGTH, NX_AXIS_FACE_HEIGHT,
165 NX_R_SHIN_TO_HEAD, NX_TOL_NORMAL, NX_FAMILY_LINEAR)
166 nx_canon_set(canon, 21, NX_AXIS_FEMUR_LENGTH, NX_AXIS_SHIN_LENGTH,
167 NX_PHI_INV_Q10 + 391, NX_TOL_LOOSE, NX_FAMILY_PHI)
168 nx_canon_set(canon, 22, NX_AXIS_HAND_LENGTH, NX_AXIS_FACE_HEIGHT,
169 NX_R_HAND_TO_FACE_H, NX_TOL_NORMAL, NX_FAMILY_LINEAR)
170 nx_canon_set(canon, 23, NX_AXIS_FOOT_LENGTH, NX_AXIS_FACE_HEIGHT,
171 NX_R_FOOT_TO_FACE_H, NX_TOL_NORMAL, NX_FAMILY_LINEAR)
172
173 // Reserve trailing slots (zeroed by sys_mmap) for future canon entries.
174 nx_canon_set(canon, 24, 0, 0, 0, 0, 0)
175 nx_canon_set(canon, 25, 0, 0, 0, 0, 0)
176 nx_canon_set(canon, 26, 0, 0, 0, 0, 0)
177 nx_canon_set(canon, 27, 0, 0, 0, 0, 0)
178 nx_canon_set(canon, 28, 0, 0, 0, 0, 0)
179 nx_canon_set(canon, 29, 0, 0, 0, 0, 0)
180 return 0
181}
182
183// Find canon entry index by (num_axis, den_axis). Returns -1 if not present.
184func nx_canon_find(canon: *i64, num_axis: i64, den_axis: i64) -> i64 {
185 var i: i64 = 0
186 while i < NX_CANON_ENTRY_COUNT {
187 let n: i64 = nx_canon_get(canon, i, NX_CANON_FIELD_NUM_AXIS)
188 let d: i64 = nx_canon_get(canon, i, NX_CANON_FIELD_DEN_AXIS)
189 if n == num_axis {
190 if d == den_axis { return i }
191 }
192 i = i + 1
193 }
194 return -1
195}