code wiki / (root) / nx_geom_test.nx

nx_geom_test.nx source

↩ module page · 144 lines · 5214 B

1// nx_geom_test.nx -- smoke for V4 geometric primitives. 2 3import "syscalls.nx" 4import "nx_image.nx" 5import "nx_features.nx" 6import "nx_geom.nx" 7 8func main() -> i64 { 9 // === Test 1: integer sqrt === 10 if nx_math_isqrt(0) != 0 { return 1 } 11 if nx_math_isqrt(1) != 1 { return 2 } 12 if nx_math_isqrt(4) != 2 { return 3 } 13 if nx_math_isqrt(9) != 3 { return 4 } 14 if nx_math_isqrt(100) != 10 { return 5 } 15 if nx_math_isqrt(10000) != 100 { return 6 } 16 // sqrt(50) = 7.07... -> floor = 7 17 if nx_math_isqrt(50) != 7 { return 7 } 18 19 // === Test 2: trig table self-consistency === 20 let cos_t: *i64 = (sys_mmap(36 * 8)) as *i64 21 let sin_t: *i64 = (sys_mmap(36 * 8)) as *i64 22 nx_geom_fill_trig(cos_t, sin_t) 23 // cos(0) = 1024, sin(0) = 0 24 if cos_t[0] != 1024 { return 10 } 25 if sin_t[0] != 0 { return 11 } 26 // cos(90) = 0, sin(90) = 1024 27 if cos_t[18] != 0 { return 12 } 28 if sin_t[18] != 1024 { return 13 } 29 // cos(45) = sin(45) -- both should be 724 30 if cos_t[9] != 724 { return 14 } 31 if sin_t[9] != 724 { return 15 } 32 // Pythagorean check: cos^2 + sin^2 ~= Q^2 (allow +-2% slop) 33 // for theta=30: cos=887, sin=512 -> 887^2 + 512^2 = 786769 + 262144 = 1048913 34 // Q^2 = 1024*1024 = 1048576, diff = 337 -> 0.03% off, perfect 35 let p_sum: i64 = cos_t[6] * cos_t[6] + sin_t[6] * sin_t[6] 36 if p_sum < 1030000 { return 16 } 37 if p_sum > 1070000 { return 17 } 38 39 // === Test 3: Hough line on a vertical line at x=16 in 32x32 image === 40 let img1: *Image = nx_image_alloc(32, 32, 1) 41 var y: i64 = 0 42 while y < 32 { 43 nx_image_set(img1, 16, y, 0, 255) 44 y = y + 1 45 } 46 // Vertical line: theta=0 degrees, rho=16. 47 // Each pixel votes; should accumulate ~32 votes at (theta=0, rho=16). 48 let lines1: *HoughLines = nx_geom_hough_line(img1, 20, 10) 49 // Should find at least one line. 50 if lines1.n_lines == 0 { return 20 } 51 // Top line should be at theta=0, rho=16 (vertical line). 52 var found_vert: i64 = 0 53 var li: i64 = 0 54 while li < lines1.n_lines { 55 if lines1.thetas[li] == 0 { 56 // rho should be ~16 (allow +-2 due to discretization) 57 if lines1.rhos[li] >= 14 { 58 if lines1.rhos[li] <= 18 { 59 if lines1.votes[li] >= 20 { 60 found_vert = 1 61 } 62 } 63 } 64 } 65 li = li + 1 66 } 67 if found_vert != 1 { return 21 } 68 69 // === Test 4: Hough line on a horizontal line at y=16 === 70 let img2: *Image = nx_image_alloc(32, 32, 1) 71 var x2: i64 = 0 72 while x2 < 32 { 73 nx_image_set(img2, x2, 16, 0, 255) 74 x2 = x2 + 1 75 } 76 let lines2: *HoughLines = nx_geom_hough_line(img2, 20, 10) 77 if lines2.n_lines == 0 { return 30 } 78 // Horizontal line: theta=90 degrees, rho=16. 79 var found_horz: i64 = 0 80 var li2: i64 = 0 81 while li2 < lines2.n_lines { 82 if lines2.thetas[li2] == 90 { 83 if lines2.rhos[li2] >= 14 { 84 if lines2.rhos[li2] <= 18 { 85 found_horz = 1 86 } 87 } 88 } 89 li2 = li2 + 1 90 } 91 if found_horz != 1 { return 31 } 92 93 // === Test 5: line-orientation histogram === 94 let hist: *i64 = (sys_mmap(36 * 8)) as *i64 95 nx_geom_line_orientation_hist(lines2, hist) 96 // Bin 18 (theta=90) should have votes; bin 0 should be ~0. 97 if hist[18] < 20 { return 40 } 98 99 // === Test 6: Hough circle on a circle of radius 6 centered at (16,16) in 32x32 === 100 let img3: *Image = nx_image_alloc(32, 32, 1) 101 // Rasterize circle using Bresenham-ish discrete points. 102 var ang: i64 = 0 103 while ang < 360 { 104 // Use cos_t/sin_t for 5-degree resolution. 105 let ai: i64 = ang / 10 106 // We have 36 angles for 0..175. For 180..355, mirror. 107 var cx_off: i64 = 0 108 var cy_off: i64 = 0 109 if ai < 36 { 110 cx_off = (6 * cos_t[ai]) / 1024 111 cy_off = (6 * sin_t[ai]) / 1024 112 } 113 if ai >= 36 { 114 // angles 180..355 -> negate both 115 let ai2: i64 = ai - 36 116 cx_off = -(6 * cos_t[ai2]) / 1024 117 cy_off = -(6 * sin_t[ai2]) / 1024 118 } 119 let px: i64 = 16 + cx_off 120 let py: i64 = 16 + cy_off 121 if px >= 0 { if px < 32 { if py >= 0 { if py < 32 { 122 nx_image_set(img3, px, py, 0, 255) 123 }}}} 124 ang = ang + 10 125 } 126 // Compute gradients on the rasterized circle. 127 let gx: *ImageS64 = nx_image_sobel_x(img3) 128 let gy: *ImageS64 = nx_image_sobel_y(img3) 129 let cir: *HoughCircles = nx_geom_hough_circle_r(img3, gx, gy, 6, 3, 10) 130 if cir.n_circles == 0 { return 50 } 131 // Should find a center near (16, 16). 132 var found_center: i64 = 0 133 var ci: i64 = 0 134 while ci < cir.n_circles { 135 let dx: i64 = cir.cxs[ci] - 16 136 let dy: i64 = cir.cys[ci] - 16 137 let d2: i64 = dx * dx + dy * dy 138 if d2 <= 9 { found_center = 1 } // within 3 pixels 139 ci = ci + 1 140 } 141 if found_center != 1 { return 51 } 142 143 return 0 144}