code wiki / _hdl_build / nx_geo_raster.nx

nx_geo_raster.nx source

↩ module page · 76 lines · 2798 B

1// nx_geo_raster.nx -- LIB: GEO-020 RASTER RENDER (integer scanline polygon fill, even-odd rule). 2// 3// THE EXCEED ANGLE (measured): coverage is decided by INTEGER scanline crossings -- for each pixel row 4// we find the polygon-edge x-crossings, sort them, and fill the spans between crossing pairs. ZERO 5// floating point, half-open [lo,hi) edge rule -> a deterministic, gap-free, no-double-fill rasterization 6// (the classic float rasterizer's seam/overlap artifacts at shared edges cannot occur). The same 7// integer cross-style interpolation as the rest of nx_geo. Pixel (row,col) at grid[row*w + col]. 8// 9// Convention (matches nx_geo): poly = flat [y0,x0, y1,x1, ...] in PIXEL coords (y=row, x=col). 10// Writes 1 to filled pixels of grid (a w*h byte buffer), returns the filled pixel count. license_tier: ORIGINAL 11import "nx_syscalls.nx" 12 13func geo_raster_fill(poly: *i64, npts: i64, w: i64, h: i64, grid: *u8) -> i64 { 14 var t: i64 = 0 15 while t < w * h { grid[t] = 0 as u8; t = t + 1 } 16 17 let xs: *i64 = sys_mmap(8 * (npts + 2)) as *i64 18 var count: i64 = 0 19 var y: i64 = 0 20 while y < h { 21 // collect edge x-crossings for scanline row y (half-open [lo,hi) in row) 22 var c: i64 = 0 23 var i: i64 = 0 24 var j: i64 = npts - 1 25 while i < npts { 26 var lo: i64 = poly[j * 2] 27 var hi: i64 = poly[i * 2] 28 var xlo: i64 = poly[j * 2 + 1] 29 var xhi: i64 = poly[i * 2 + 1] 30 if lo > hi { 31 let ty: i64 = lo; lo = hi; hi = ty 32 let tx: i64 = xlo; xlo = xhi; xhi = tx 33 } 34 if y >= lo { if y < hi { 35 xs[c] = xlo + (xhi - xlo) * (y - lo) / (hi - lo) 36 c = c + 1 37 } } 38 j = i 39 i = i + 1 40 } 41 // sort crossings ascending (selection sort; c is small) 42 var a: i64 = 0 43 while a < c { 44 var mn: i64 = a 45 var b: i64 = a + 1 46 while b < c { 47 if xs[b] < xs[mn] { mn = b } 48 b = b + 1 49 } 50 let tmp: i64 = xs[a]; xs[a] = xs[mn]; xs[mn] = tmp 51 a = a + 1 52 } 53 // fill spans between crossing pairs 54 var k: i64 = 0 55 while k + 1 < c { 56 var xa: i64 = xs[k] 57 var xb: i64 = xs[k + 1] 58 if xa < 0 { xa = 0 } 59 if xb > w { xb = w } 60 var col: i64 = xa 61 while col < xb { 62 grid[y * w + col] = 1 as u8 63 count = count + 1 64 col = col + 1 65 } 66 k = k + 2 67 } 68 y = y + 1 69 } 70 return count 71} 72 73// read a pixel (1=filled, 0=empty). 74func geo_raster_get(grid: *u8, w: i64, row: i64, col: i64) -> i64 { 75 return grid[row * w + col] as i64 76}