Skip to main content

ScanlineInterp

Struct ScanlineInterp 

Source
pub struct ScanlineInterp { /* private fields */ }
Expand description

Per-scanline interpolator for z-buffer depth and (u, v) texture coordinates.

Pre-computes Q16.16 per-pixel step values for z, u, and v so the inner loop only does three wrapping additions instead of floating-point divisions per pixel — useful for MCU scanline rasterization.

§Usage

let mut interp = ScanlineInterp::new(
    left_z,  right_z,   // u32 depth values (Q16.16)
    left_u,  right_u,   // u32 U texture coords (Q16.16)
    left_v,  right_v,   // u32 V texture coords (Q16.16)
    span_pixels,         // number of pixels across the scanline
);

for _x in 0..=span_pixels {
    let z = interp.z();
    let u = interp.u();
    let v = interp.v();
    // ... depth test, texture sample, write pixel ...
    interp.step();
}

Implementations§

Source§

impl ScanlineInterp

Source

pub fn new( z_left: u32, z_right: u32, u_left: u32, u_right: u32, v_left: u32, v_right: u32, span: i32, ) -> Self

Create a new scanline interpolator.

§Arguments
  • z_left, z_right — depth at the left and right scanline endpoints (Q16.16 u32)
  • u_left, u_right — U texture coordinates (Q16.16 u32, range [0, 65536])
  • v_left, v_right — V texture coordinates (Q16.16 u32, range [0, 65536])
  • span — number of pixels across the scanline (0 is valid — returns left values)
Examples found in repository?
examples/spatial_vision_processing.rs (line 196)
25fn main() {
26    println!("===============================================================================");
27    println!("        embedded-dsp 2D Spatial Processing & Embedded Vision                   ");
28    println!("===============================================================================");
29    println!();
30
31    // -----------------------------------------------------------------------------------------
32    // 1. Synthetic 8x8 Sensor Matrix with Block Feature & Salt-and-Pepper Noise
33    // -----------------------------------------------------------------------------------------
34    println!("--- 1. Synthetic 8x8 Image Matrix with Feature & Noise ---");
35    let mut raw_image = [0.0f32; 64];
36
37    // Create a 4x4 high-intensity square in the center
38    for r in 2..6 {
39        for c in 2..6 {
40            raw_image[r * 8 + c] = 20.0;
41        }
42    }
43
44    // Add salt-and-pepper impulsive noise pixels
45    raw_image[1] = 50.0; // Salt noise
46    raw_image[15] = 50.0; // Salt noise
47    raw_image[3 * 8 + 3] = 0.0; // Pepper noise inside feature
48    raw_image[6 * 8 + 2] = 50.0; // Salt noise
49
50    print_matrix_8x8("Raw 8x8 Sensor Image", &raw_image);
51
52    // -----------------------------------------------------------------------------------------
53    // 2. 2D Spatial Convolution (Gaussian Blur & Sharpening)
54    // -----------------------------------------------------------------------------------------
55    println!("\n--- 2. 2D Spatial Convolution (Smoothing & Sharpening) ---");
56    // 3x3 Gaussian Blur Kernel
57    let gaussian_kernel: [f32; 9] = [1.0, 2.0, 1.0, 2.0, 4.0, 2.0, 1.0, 2.0, 1.0];
58    let mut blurred_image = [0.0f32; 64];
59    let status = convolve2d_f32(
60        &raw_image,
61        &mut blurred_image,
62        8,
63        8,
64        &gaussian_kernel,
65        3,
66        3,
67        true,
68    );
69    println!("  Gaussian 3x3 Convolution Status: {:?}", status);
70    print_matrix_8x8("Gaussian Filtered Image (Smoothed)", &blurred_image);
71
72    // 3x3 Sharpening Kernel
73    let sharpen_kernel: [f32; 9] = [0.0, -1.0, 0.0, -1.0, 5.0, -1.0, 0.0, -1.0, 0.0];
74    let mut sharpened_image = [0.0f32; 64];
75    convolve2d_f32(
76        &blurred_image,
77        &mut sharpened_image,
78        8,
79        8,
80        &sharpen_kernel,
81        3,
82        3,
83        false,
84    );
85    print_matrix_8x8("Sharpened Image", &sharpened_image);
86
87    // -----------------------------------------------------------------------------------------
88    // 3. Non-Linear 2D Filtering (Min, Max, Median Despeckling)
89    // -----------------------------------------------------------------------------------------
90    println!("\n--- 3. Non-Linear 2D Filtering (Despeckling & Morphological Filters) ---");
91    let mut median_cleaned = [0.0f32; 64];
92    let mut min_filtered = [0.0f32; 64];
93    let mut max_filtered = [0.0f32; 64];
94
95    // 3x3 Median filter removes impulsive salt & pepper noise while preserving sharp boundaries
96    nonlin2d_filter_f32(
97        &raw_image,
98        &mut median_cleaned,
99        8,
100        8,
101        3,
102        NonlinFilterType::Median,
103    );
104    print_matrix_8x8("3x3 Median Filtered Image (Noise Removed)", &median_cleaned);
105
106    // Morphological erosion (Min) and dilation (Max)
107    nonlin2d_filter_f32(
108        &median_cleaned,
109        &mut min_filtered,
110        8,
111        8,
112        3,
113        NonlinFilterType::Min,
114    );
115    nonlin2d_filter_f32(
116        &median_cleaned,
117        &mut max_filtered,
118        8,
119        8,
120        3,
121        NonlinFilterType::Max,
122    );
123    println!("  Morphological Erosion (Min) & Dilation (Max) computed successfully.");
124
125    // -----------------------------------------------------------------------------------------
126    // 4. 2D Sobel Edge Detection
127    // -----------------------------------------------------------------------------------------
128    println!("\n--- 4. 2D Sobel Edge Detection (Horizontal + Vertical Gradients) ---");
129    let mut edges = [0.0f32; 64];
130    // Threshold set to 15.0 to detect the boundaries of the central block
131    sobel_edge_detection_f32(&median_cleaned, &mut edges, 8, 8, 15.0);
132    print_matrix_8x8(
133        "Sobel Binary Edge Map (1.0 = Edge, 0.0 = Background)",
134        &edges,
135    );
136
137    // -----------------------------------------------------------------------------------------
138    // 5. 2D DCT-II Transform & Energy Compaction (JPEG Block Transform)
139    // -----------------------------------------------------------------------------------------
140    println!("\n--- 5. 2D Discrete Cosine Transform (DCT-II) & Inverse DCT-II ---");
141    let mut dct_coeffs = [0.0f32; 64];
142    let mut reconstructed_image = [0.0f32; 64];
143
144    dct2d_f32(&median_cleaned, &mut dct_coeffs, 8, 8);
145    println!(
146        "  2D DCT DC Coefficient (Top-Left Energy) = {:.2}",
147        dct_coeffs[0]
148    );
149    println!("  Top 2x2 Low-Frequency DCT Coefficients:");
150    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[0], dct_coeffs[1]);
151    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[8], dct_coeffs[9]);
152
153    // Reconstruct via 2D IDCT
154    idct2d_f32(&dct_coeffs, &mut reconstructed_image, 8, 8);
155    let mut recon_diff = 0.0f32;
156    for i in 0..64 {
157        recon_diff += (reconstructed_image[i] - median_cleaned[i]).abs();
158    }
159    println!(
160        "  2D IDCT Exact Reconstruction Absolute Error Sum: {:.2e}",
161        recon_diff
162    );
163
164    // -----------------------------------------------------------------------------------------
165    // 6. Quantitative Image Quality Metrics (Histogram, MSE, PSNR)
166    // -----------------------------------------------------------------------------------------
167    println!("\n--- 6. Image Metrics: 2D Histogram, MSE, and PSNR ---");
168    let mut hist_bins = [0usize; 5]; // 5 bins covering range 0.0 .. 50.0
169    histogram_2d_f32(&raw_image, &mut hist_bins, 0.0, 50.0);
170    println!(
171        "  2D Image Intensity Histogram (5 bins across 0..50): {:?}",
172        hist_bins
173    );
174
175    let mse = mse_2d_f32(&raw_image, &median_cleaned);
176    let psnr = psnr_2d_f32(&raw_image, &median_cleaned, 50.0);
177    println!("  Raw Noisy vs Median Cleaned Image:");
178    println!("    • Mean Squared Error (MSE)       : {:.2}", mse);
179    println!("    • Peak Signal-to-Noise Ratio (PSNR): {:.2} dB", psnr);
180
181    // -----------------------------------------------------------------------------------------
182    // 7. Q16.16 Fixed-Point Rasterizer & Scanline Interpolation
183    // -----------------------------------------------------------------------------------------
184    println!("\n--- 7. Q16.16 Fixed-Point Scanline Interpolation (MCU Graphics / Rasterizer) ---");
185    // Span of 10 pixels across scanline
186    let span = 10;
187    // Left endpoint: Depth z = 1.0 (Q16.16 = 65536), Texture u = 0.0, v = 0.0
188    // Right endpoint: Depth z = 5.0 (Q16.16 = 327680), Texture u = 1.0 (65536), v = 1.0 (65536)
189    let left_z = to_q16(1.0) as u32;
190    let right_z = to_q16(5.0) as u32;
191    let left_u = to_q16(0.0) as u32;
192    let right_u = to_q16(1.0) as u32;
193    let left_v = to_q16(0.0) as u32;
194    let right_v = to_q16(1.0) as u32;
195
196    let mut scanline = ScanlineInterp::new(left_z, right_z, left_u, right_u, left_v, right_v, span);
197
198    println!("  Interpolating 10 Pixels Across Fixed-Point Scanline (Q16.16):");
199    println!(
200        "    {:<5} {:<12} {:<12} {:<12}",
201        "Pixel", "Depth (z)", "Texcoord (u)", "Texcoord (v)"
202    );
203    println!("    --------------------------------------------------");
204
205    for px in 0..=span {
206        let z_val = from_q16(scanline.z() as i32);
207        let u_val = from_q16(scanline.u() as i32);
208        let v_val = from_q16(scanline.v() as i32);
209
210        if px == 0 || px == 5 || px == span {
211            println!(
212                "    {:<5} {:<12.3} {:<12.3} {:<12.3}",
213                px, z_val, u_val, v_val
214            );
215        }
216        scanline.step();
217    }
218
219    // Fixed-Point arithmetic helpers
220    let a_q16 = to_q16(3.5);
221    let b_q16 = to_q16(2.0);
222    let prod_q16 = mul_q16(a_q16, b_q16);
223    let div_res_q16 = div_q16(a_q16, b_q16);
224    let lerp_res_q16 = lerp_q16(a_q16, b_q16, 5, 10);
225
226    println!("\n  Q16.16 Arithmetic Verification:");
227    println!(
228        "    • mul_q16(3.5, 2.0)   = {:.3} (expected 7.000)",
229        from_q16(prod_q16)
230    );
231    println!(
232        "    • div_q16(3.5, 2.0)   = {:.3} (expected 1.750)",
233        from_q16(div_res_q16)
234    );
235    println!(
236        "    • lerp_q16(3.5, 2.0)  = {:.3} (expected 2.750)",
237        from_q16(lerp_res_q16)
238    );
239
240    println!();
241    println!("===============================================================================");
242    println!("             2D Spatial & Vision Pipeline Execution Complete!                  ");
243    println!("===============================================================================");
244}
Source

pub fn depth_only(z_left: u32, z_right: u32, span: i32) -> Self

Create an interpolator for depth-only scanlines (no texture mapping).

Source

pub fn z(&self) -> u32

Current depth value (Q16.16 u32).

Examples found in repository?
examples/spatial_vision_processing.rs (line 206)
25fn main() {
26    println!("===============================================================================");
27    println!("        embedded-dsp 2D Spatial Processing & Embedded Vision                   ");
28    println!("===============================================================================");
29    println!();
30
31    // -----------------------------------------------------------------------------------------
32    // 1. Synthetic 8x8 Sensor Matrix with Block Feature & Salt-and-Pepper Noise
33    // -----------------------------------------------------------------------------------------
34    println!("--- 1. Synthetic 8x8 Image Matrix with Feature & Noise ---");
35    let mut raw_image = [0.0f32; 64];
36
37    // Create a 4x4 high-intensity square in the center
38    for r in 2..6 {
39        for c in 2..6 {
40            raw_image[r * 8 + c] = 20.0;
41        }
42    }
43
44    // Add salt-and-pepper impulsive noise pixels
45    raw_image[1] = 50.0; // Salt noise
46    raw_image[15] = 50.0; // Salt noise
47    raw_image[3 * 8 + 3] = 0.0; // Pepper noise inside feature
48    raw_image[6 * 8 + 2] = 50.0; // Salt noise
49
50    print_matrix_8x8("Raw 8x8 Sensor Image", &raw_image);
51
52    // -----------------------------------------------------------------------------------------
53    // 2. 2D Spatial Convolution (Gaussian Blur & Sharpening)
54    // -----------------------------------------------------------------------------------------
55    println!("\n--- 2. 2D Spatial Convolution (Smoothing & Sharpening) ---");
56    // 3x3 Gaussian Blur Kernel
57    let gaussian_kernel: [f32; 9] = [1.0, 2.0, 1.0, 2.0, 4.0, 2.0, 1.0, 2.0, 1.0];
58    let mut blurred_image = [0.0f32; 64];
59    let status = convolve2d_f32(
60        &raw_image,
61        &mut blurred_image,
62        8,
63        8,
64        &gaussian_kernel,
65        3,
66        3,
67        true,
68    );
69    println!("  Gaussian 3x3 Convolution Status: {:?}", status);
70    print_matrix_8x8("Gaussian Filtered Image (Smoothed)", &blurred_image);
71
72    // 3x3 Sharpening Kernel
73    let sharpen_kernel: [f32; 9] = [0.0, -1.0, 0.0, -1.0, 5.0, -1.0, 0.0, -1.0, 0.0];
74    let mut sharpened_image = [0.0f32; 64];
75    convolve2d_f32(
76        &blurred_image,
77        &mut sharpened_image,
78        8,
79        8,
80        &sharpen_kernel,
81        3,
82        3,
83        false,
84    );
85    print_matrix_8x8("Sharpened Image", &sharpened_image);
86
87    // -----------------------------------------------------------------------------------------
88    // 3. Non-Linear 2D Filtering (Min, Max, Median Despeckling)
89    // -----------------------------------------------------------------------------------------
90    println!("\n--- 3. Non-Linear 2D Filtering (Despeckling & Morphological Filters) ---");
91    let mut median_cleaned = [0.0f32; 64];
92    let mut min_filtered = [0.0f32; 64];
93    let mut max_filtered = [0.0f32; 64];
94
95    // 3x3 Median filter removes impulsive salt & pepper noise while preserving sharp boundaries
96    nonlin2d_filter_f32(
97        &raw_image,
98        &mut median_cleaned,
99        8,
100        8,
101        3,
102        NonlinFilterType::Median,
103    );
104    print_matrix_8x8("3x3 Median Filtered Image (Noise Removed)", &median_cleaned);
105
106    // Morphological erosion (Min) and dilation (Max)
107    nonlin2d_filter_f32(
108        &median_cleaned,
109        &mut min_filtered,
110        8,
111        8,
112        3,
113        NonlinFilterType::Min,
114    );
115    nonlin2d_filter_f32(
116        &median_cleaned,
117        &mut max_filtered,
118        8,
119        8,
120        3,
121        NonlinFilterType::Max,
122    );
123    println!("  Morphological Erosion (Min) & Dilation (Max) computed successfully.");
124
125    // -----------------------------------------------------------------------------------------
126    // 4. 2D Sobel Edge Detection
127    // -----------------------------------------------------------------------------------------
128    println!("\n--- 4. 2D Sobel Edge Detection (Horizontal + Vertical Gradients) ---");
129    let mut edges = [0.0f32; 64];
130    // Threshold set to 15.0 to detect the boundaries of the central block
131    sobel_edge_detection_f32(&median_cleaned, &mut edges, 8, 8, 15.0);
132    print_matrix_8x8(
133        "Sobel Binary Edge Map (1.0 = Edge, 0.0 = Background)",
134        &edges,
135    );
136
137    // -----------------------------------------------------------------------------------------
138    // 5. 2D DCT-II Transform & Energy Compaction (JPEG Block Transform)
139    // -----------------------------------------------------------------------------------------
140    println!("\n--- 5. 2D Discrete Cosine Transform (DCT-II) & Inverse DCT-II ---");
141    let mut dct_coeffs = [0.0f32; 64];
142    let mut reconstructed_image = [0.0f32; 64];
143
144    dct2d_f32(&median_cleaned, &mut dct_coeffs, 8, 8);
145    println!(
146        "  2D DCT DC Coefficient (Top-Left Energy) = {:.2}",
147        dct_coeffs[0]
148    );
149    println!("  Top 2x2 Low-Frequency DCT Coefficients:");
150    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[0], dct_coeffs[1]);
151    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[8], dct_coeffs[9]);
152
153    // Reconstruct via 2D IDCT
154    idct2d_f32(&dct_coeffs, &mut reconstructed_image, 8, 8);
155    let mut recon_diff = 0.0f32;
156    for i in 0..64 {
157        recon_diff += (reconstructed_image[i] - median_cleaned[i]).abs();
158    }
159    println!(
160        "  2D IDCT Exact Reconstruction Absolute Error Sum: {:.2e}",
161        recon_diff
162    );
163
164    // -----------------------------------------------------------------------------------------
165    // 6. Quantitative Image Quality Metrics (Histogram, MSE, PSNR)
166    // -----------------------------------------------------------------------------------------
167    println!("\n--- 6. Image Metrics: 2D Histogram, MSE, and PSNR ---");
168    let mut hist_bins = [0usize; 5]; // 5 bins covering range 0.0 .. 50.0
169    histogram_2d_f32(&raw_image, &mut hist_bins, 0.0, 50.0);
170    println!(
171        "  2D Image Intensity Histogram (5 bins across 0..50): {:?}",
172        hist_bins
173    );
174
175    let mse = mse_2d_f32(&raw_image, &median_cleaned);
176    let psnr = psnr_2d_f32(&raw_image, &median_cleaned, 50.0);
177    println!("  Raw Noisy vs Median Cleaned Image:");
178    println!("    • Mean Squared Error (MSE)       : {:.2}", mse);
179    println!("    • Peak Signal-to-Noise Ratio (PSNR): {:.2} dB", psnr);
180
181    // -----------------------------------------------------------------------------------------
182    // 7. Q16.16 Fixed-Point Rasterizer & Scanline Interpolation
183    // -----------------------------------------------------------------------------------------
184    println!("\n--- 7. Q16.16 Fixed-Point Scanline Interpolation (MCU Graphics / Rasterizer) ---");
185    // Span of 10 pixels across scanline
186    let span = 10;
187    // Left endpoint: Depth z = 1.0 (Q16.16 = 65536), Texture u = 0.0, v = 0.0
188    // Right endpoint: Depth z = 5.0 (Q16.16 = 327680), Texture u = 1.0 (65536), v = 1.0 (65536)
189    let left_z = to_q16(1.0) as u32;
190    let right_z = to_q16(5.0) as u32;
191    let left_u = to_q16(0.0) as u32;
192    let right_u = to_q16(1.0) as u32;
193    let left_v = to_q16(0.0) as u32;
194    let right_v = to_q16(1.0) as u32;
195
196    let mut scanline = ScanlineInterp::new(left_z, right_z, left_u, right_u, left_v, right_v, span);
197
198    println!("  Interpolating 10 Pixels Across Fixed-Point Scanline (Q16.16):");
199    println!(
200        "    {:<5} {:<12} {:<12} {:<12}",
201        "Pixel", "Depth (z)", "Texcoord (u)", "Texcoord (v)"
202    );
203    println!("    --------------------------------------------------");
204
205    for px in 0..=span {
206        let z_val = from_q16(scanline.z() as i32);
207        let u_val = from_q16(scanline.u() as i32);
208        let v_val = from_q16(scanline.v() as i32);
209
210        if px == 0 || px == 5 || px == span {
211            println!(
212                "    {:<5} {:<12.3} {:<12.3} {:<12.3}",
213                px, z_val, u_val, v_val
214            );
215        }
216        scanline.step();
217    }
218
219    // Fixed-Point arithmetic helpers
220    let a_q16 = to_q16(3.5);
221    let b_q16 = to_q16(2.0);
222    let prod_q16 = mul_q16(a_q16, b_q16);
223    let div_res_q16 = div_q16(a_q16, b_q16);
224    let lerp_res_q16 = lerp_q16(a_q16, b_q16, 5, 10);
225
226    println!("\n  Q16.16 Arithmetic Verification:");
227    println!(
228        "    • mul_q16(3.5, 2.0)   = {:.3} (expected 7.000)",
229        from_q16(prod_q16)
230    );
231    println!(
232        "    • div_q16(3.5, 2.0)   = {:.3} (expected 1.750)",
233        from_q16(div_res_q16)
234    );
235    println!(
236        "    • lerp_q16(3.5, 2.0)  = {:.3} (expected 2.750)",
237        from_q16(lerp_res_q16)
238    );
239
240    println!();
241    println!("===============================================================================");
242    println!("             2D Spatial & Vision Pipeline Execution Complete!                  ");
243    println!("===============================================================================");
244}
Source

pub fn u(&self) -> u32

Current U texture coordinate (Q16.16 u32).

Examples found in repository?
examples/spatial_vision_processing.rs (line 207)
25fn main() {
26    println!("===============================================================================");
27    println!("        embedded-dsp 2D Spatial Processing & Embedded Vision                   ");
28    println!("===============================================================================");
29    println!();
30
31    // -----------------------------------------------------------------------------------------
32    // 1. Synthetic 8x8 Sensor Matrix with Block Feature & Salt-and-Pepper Noise
33    // -----------------------------------------------------------------------------------------
34    println!("--- 1. Synthetic 8x8 Image Matrix with Feature & Noise ---");
35    let mut raw_image = [0.0f32; 64];
36
37    // Create a 4x4 high-intensity square in the center
38    for r in 2..6 {
39        for c in 2..6 {
40            raw_image[r * 8 + c] = 20.0;
41        }
42    }
43
44    // Add salt-and-pepper impulsive noise pixels
45    raw_image[1] = 50.0; // Salt noise
46    raw_image[15] = 50.0; // Salt noise
47    raw_image[3 * 8 + 3] = 0.0; // Pepper noise inside feature
48    raw_image[6 * 8 + 2] = 50.0; // Salt noise
49
50    print_matrix_8x8("Raw 8x8 Sensor Image", &raw_image);
51
52    // -----------------------------------------------------------------------------------------
53    // 2. 2D Spatial Convolution (Gaussian Blur & Sharpening)
54    // -----------------------------------------------------------------------------------------
55    println!("\n--- 2. 2D Spatial Convolution (Smoothing & Sharpening) ---");
56    // 3x3 Gaussian Blur Kernel
57    let gaussian_kernel: [f32; 9] = [1.0, 2.0, 1.0, 2.0, 4.0, 2.0, 1.0, 2.0, 1.0];
58    let mut blurred_image = [0.0f32; 64];
59    let status = convolve2d_f32(
60        &raw_image,
61        &mut blurred_image,
62        8,
63        8,
64        &gaussian_kernel,
65        3,
66        3,
67        true,
68    );
69    println!("  Gaussian 3x3 Convolution Status: {:?}", status);
70    print_matrix_8x8("Gaussian Filtered Image (Smoothed)", &blurred_image);
71
72    // 3x3 Sharpening Kernel
73    let sharpen_kernel: [f32; 9] = [0.0, -1.0, 0.0, -1.0, 5.0, -1.0, 0.0, -1.0, 0.0];
74    let mut sharpened_image = [0.0f32; 64];
75    convolve2d_f32(
76        &blurred_image,
77        &mut sharpened_image,
78        8,
79        8,
80        &sharpen_kernel,
81        3,
82        3,
83        false,
84    );
85    print_matrix_8x8("Sharpened Image", &sharpened_image);
86
87    // -----------------------------------------------------------------------------------------
88    // 3. Non-Linear 2D Filtering (Min, Max, Median Despeckling)
89    // -----------------------------------------------------------------------------------------
90    println!("\n--- 3. Non-Linear 2D Filtering (Despeckling & Morphological Filters) ---");
91    let mut median_cleaned = [0.0f32; 64];
92    let mut min_filtered = [0.0f32; 64];
93    let mut max_filtered = [0.0f32; 64];
94
95    // 3x3 Median filter removes impulsive salt & pepper noise while preserving sharp boundaries
96    nonlin2d_filter_f32(
97        &raw_image,
98        &mut median_cleaned,
99        8,
100        8,
101        3,
102        NonlinFilterType::Median,
103    );
104    print_matrix_8x8("3x3 Median Filtered Image (Noise Removed)", &median_cleaned);
105
106    // Morphological erosion (Min) and dilation (Max)
107    nonlin2d_filter_f32(
108        &median_cleaned,
109        &mut min_filtered,
110        8,
111        8,
112        3,
113        NonlinFilterType::Min,
114    );
115    nonlin2d_filter_f32(
116        &median_cleaned,
117        &mut max_filtered,
118        8,
119        8,
120        3,
121        NonlinFilterType::Max,
122    );
123    println!("  Morphological Erosion (Min) & Dilation (Max) computed successfully.");
124
125    // -----------------------------------------------------------------------------------------
126    // 4. 2D Sobel Edge Detection
127    // -----------------------------------------------------------------------------------------
128    println!("\n--- 4. 2D Sobel Edge Detection (Horizontal + Vertical Gradients) ---");
129    let mut edges = [0.0f32; 64];
130    // Threshold set to 15.0 to detect the boundaries of the central block
131    sobel_edge_detection_f32(&median_cleaned, &mut edges, 8, 8, 15.0);
132    print_matrix_8x8(
133        "Sobel Binary Edge Map (1.0 = Edge, 0.0 = Background)",
134        &edges,
135    );
136
137    // -----------------------------------------------------------------------------------------
138    // 5. 2D DCT-II Transform & Energy Compaction (JPEG Block Transform)
139    // -----------------------------------------------------------------------------------------
140    println!("\n--- 5. 2D Discrete Cosine Transform (DCT-II) & Inverse DCT-II ---");
141    let mut dct_coeffs = [0.0f32; 64];
142    let mut reconstructed_image = [0.0f32; 64];
143
144    dct2d_f32(&median_cleaned, &mut dct_coeffs, 8, 8);
145    println!(
146        "  2D DCT DC Coefficient (Top-Left Energy) = {:.2}",
147        dct_coeffs[0]
148    );
149    println!("  Top 2x2 Low-Frequency DCT Coefficients:");
150    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[0], dct_coeffs[1]);
151    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[8], dct_coeffs[9]);
152
153    // Reconstruct via 2D IDCT
154    idct2d_f32(&dct_coeffs, &mut reconstructed_image, 8, 8);
155    let mut recon_diff = 0.0f32;
156    for i in 0..64 {
157        recon_diff += (reconstructed_image[i] - median_cleaned[i]).abs();
158    }
159    println!(
160        "  2D IDCT Exact Reconstruction Absolute Error Sum: {:.2e}",
161        recon_diff
162    );
163
164    // -----------------------------------------------------------------------------------------
165    // 6. Quantitative Image Quality Metrics (Histogram, MSE, PSNR)
166    // -----------------------------------------------------------------------------------------
167    println!("\n--- 6. Image Metrics: 2D Histogram, MSE, and PSNR ---");
168    let mut hist_bins = [0usize; 5]; // 5 bins covering range 0.0 .. 50.0
169    histogram_2d_f32(&raw_image, &mut hist_bins, 0.0, 50.0);
170    println!(
171        "  2D Image Intensity Histogram (5 bins across 0..50): {:?}",
172        hist_bins
173    );
174
175    let mse = mse_2d_f32(&raw_image, &median_cleaned);
176    let psnr = psnr_2d_f32(&raw_image, &median_cleaned, 50.0);
177    println!("  Raw Noisy vs Median Cleaned Image:");
178    println!("    • Mean Squared Error (MSE)       : {:.2}", mse);
179    println!("    • Peak Signal-to-Noise Ratio (PSNR): {:.2} dB", psnr);
180
181    // -----------------------------------------------------------------------------------------
182    // 7. Q16.16 Fixed-Point Rasterizer & Scanline Interpolation
183    // -----------------------------------------------------------------------------------------
184    println!("\n--- 7. Q16.16 Fixed-Point Scanline Interpolation (MCU Graphics / Rasterizer) ---");
185    // Span of 10 pixels across scanline
186    let span = 10;
187    // Left endpoint: Depth z = 1.0 (Q16.16 = 65536), Texture u = 0.0, v = 0.0
188    // Right endpoint: Depth z = 5.0 (Q16.16 = 327680), Texture u = 1.0 (65536), v = 1.0 (65536)
189    let left_z = to_q16(1.0) as u32;
190    let right_z = to_q16(5.0) as u32;
191    let left_u = to_q16(0.0) as u32;
192    let right_u = to_q16(1.0) as u32;
193    let left_v = to_q16(0.0) as u32;
194    let right_v = to_q16(1.0) as u32;
195
196    let mut scanline = ScanlineInterp::new(left_z, right_z, left_u, right_u, left_v, right_v, span);
197
198    println!("  Interpolating 10 Pixels Across Fixed-Point Scanline (Q16.16):");
199    println!(
200        "    {:<5} {:<12} {:<12} {:<12}",
201        "Pixel", "Depth (z)", "Texcoord (u)", "Texcoord (v)"
202    );
203    println!("    --------------------------------------------------");
204
205    for px in 0..=span {
206        let z_val = from_q16(scanline.z() as i32);
207        let u_val = from_q16(scanline.u() as i32);
208        let v_val = from_q16(scanline.v() as i32);
209
210        if px == 0 || px == 5 || px == span {
211            println!(
212                "    {:<5} {:<12.3} {:<12.3} {:<12.3}",
213                px, z_val, u_val, v_val
214            );
215        }
216        scanline.step();
217    }
218
219    // Fixed-Point arithmetic helpers
220    let a_q16 = to_q16(3.5);
221    let b_q16 = to_q16(2.0);
222    let prod_q16 = mul_q16(a_q16, b_q16);
223    let div_res_q16 = div_q16(a_q16, b_q16);
224    let lerp_res_q16 = lerp_q16(a_q16, b_q16, 5, 10);
225
226    println!("\n  Q16.16 Arithmetic Verification:");
227    println!(
228        "    • mul_q16(3.5, 2.0)   = {:.3} (expected 7.000)",
229        from_q16(prod_q16)
230    );
231    println!(
232        "    • div_q16(3.5, 2.0)   = {:.3} (expected 1.750)",
233        from_q16(div_res_q16)
234    );
235    println!(
236        "    • lerp_q16(3.5, 2.0)  = {:.3} (expected 2.750)",
237        from_q16(lerp_res_q16)
238    );
239
240    println!();
241    println!("===============================================================================");
242    println!("             2D Spatial & Vision Pipeline Execution Complete!                  ");
243    println!("===============================================================================");
244}
Source

pub fn v(&self) -> u32

Current V texture coordinate (Q16.16 u32).

Examples found in repository?
examples/spatial_vision_processing.rs (line 208)
25fn main() {
26    println!("===============================================================================");
27    println!("        embedded-dsp 2D Spatial Processing & Embedded Vision                   ");
28    println!("===============================================================================");
29    println!();
30
31    // -----------------------------------------------------------------------------------------
32    // 1. Synthetic 8x8 Sensor Matrix with Block Feature & Salt-and-Pepper Noise
33    // -----------------------------------------------------------------------------------------
34    println!("--- 1. Synthetic 8x8 Image Matrix with Feature & Noise ---");
35    let mut raw_image = [0.0f32; 64];
36
37    // Create a 4x4 high-intensity square in the center
38    for r in 2..6 {
39        for c in 2..6 {
40            raw_image[r * 8 + c] = 20.0;
41        }
42    }
43
44    // Add salt-and-pepper impulsive noise pixels
45    raw_image[1] = 50.0; // Salt noise
46    raw_image[15] = 50.0; // Salt noise
47    raw_image[3 * 8 + 3] = 0.0; // Pepper noise inside feature
48    raw_image[6 * 8 + 2] = 50.0; // Salt noise
49
50    print_matrix_8x8("Raw 8x8 Sensor Image", &raw_image);
51
52    // -----------------------------------------------------------------------------------------
53    // 2. 2D Spatial Convolution (Gaussian Blur & Sharpening)
54    // -----------------------------------------------------------------------------------------
55    println!("\n--- 2. 2D Spatial Convolution (Smoothing & Sharpening) ---");
56    // 3x3 Gaussian Blur Kernel
57    let gaussian_kernel: [f32; 9] = [1.0, 2.0, 1.0, 2.0, 4.0, 2.0, 1.0, 2.0, 1.0];
58    let mut blurred_image = [0.0f32; 64];
59    let status = convolve2d_f32(
60        &raw_image,
61        &mut blurred_image,
62        8,
63        8,
64        &gaussian_kernel,
65        3,
66        3,
67        true,
68    );
69    println!("  Gaussian 3x3 Convolution Status: {:?}", status);
70    print_matrix_8x8("Gaussian Filtered Image (Smoothed)", &blurred_image);
71
72    // 3x3 Sharpening Kernel
73    let sharpen_kernel: [f32; 9] = [0.0, -1.0, 0.0, -1.0, 5.0, -1.0, 0.0, -1.0, 0.0];
74    let mut sharpened_image = [0.0f32; 64];
75    convolve2d_f32(
76        &blurred_image,
77        &mut sharpened_image,
78        8,
79        8,
80        &sharpen_kernel,
81        3,
82        3,
83        false,
84    );
85    print_matrix_8x8("Sharpened Image", &sharpened_image);
86
87    // -----------------------------------------------------------------------------------------
88    // 3. Non-Linear 2D Filtering (Min, Max, Median Despeckling)
89    // -----------------------------------------------------------------------------------------
90    println!("\n--- 3. Non-Linear 2D Filtering (Despeckling & Morphological Filters) ---");
91    let mut median_cleaned = [0.0f32; 64];
92    let mut min_filtered = [0.0f32; 64];
93    let mut max_filtered = [0.0f32; 64];
94
95    // 3x3 Median filter removes impulsive salt & pepper noise while preserving sharp boundaries
96    nonlin2d_filter_f32(
97        &raw_image,
98        &mut median_cleaned,
99        8,
100        8,
101        3,
102        NonlinFilterType::Median,
103    );
104    print_matrix_8x8("3x3 Median Filtered Image (Noise Removed)", &median_cleaned);
105
106    // Morphological erosion (Min) and dilation (Max)
107    nonlin2d_filter_f32(
108        &median_cleaned,
109        &mut min_filtered,
110        8,
111        8,
112        3,
113        NonlinFilterType::Min,
114    );
115    nonlin2d_filter_f32(
116        &median_cleaned,
117        &mut max_filtered,
118        8,
119        8,
120        3,
121        NonlinFilterType::Max,
122    );
123    println!("  Morphological Erosion (Min) & Dilation (Max) computed successfully.");
124
125    // -----------------------------------------------------------------------------------------
126    // 4. 2D Sobel Edge Detection
127    // -----------------------------------------------------------------------------------------
128    println!("\n--- 4. 2D Sobel Edge Detection (Horizontal + Vertical Gradients) ---");
129    let mut edges = [0.0f32; 64];
130    // Threshold set to 15.0 to detect the boundaries of the central block
131    sobel_edge_detection_f32(&median_cleaned, &mut edges, 8, 8, 15.0);
132    print_matrix_8x8(
133        "Sobel Binary Edge Map (1.0 = Edge, 0.0 = Background)",
134        &edges,
135    );
136
137    // -----------------------------------------------------------------------------------------
138    // 5. 2D DCT-II Transform & Energy Compaction (JPEG Block Transform)
139    // -----------------------------------------------------------------------------------------
140    println!("\n--- 5. 2D Discrete Cosine Transform (DCT-II) & Inverse DCT-II ---");
141    let mut dct_coeffs = [0.0f32; 64];
142    let mut reconstructed_image = [0.0f32; 64];
143
144    dct2d_f32(&median_cleaned, &mut dct_coeffs, 8, 8);
145    println!(
146        "  2D DCT DC Coefficient (Top-Left Energy) = {:.2}",
147        dct_coeffs[0]
148    );
149    println!("  Top 2x2 Low-Frequency DCT Coefficients:");
150    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[0], dct_coeffs[1]);
151    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[8], dct_coeffs[9]);
152
153    // Reconstruct via 2D IDCT
154    idct2d_f32(&dct_coeffs, &mut reconstructed_image, 8, 8);
155    let mut recon_diff = 0.0f32;
156    for i in 0..64 {
157        recon_diff += (reconstructed_image[i] - median_cleaned[i]).abs();
158    }
159    println!(
160        "  2D IDCT Exact Reconstruction Absolute Error Sum: {:.2e}",
161        recon_diff
162    );
163
164    // -----------------------------------------------------------------------------------------
165    // 6. Quantitative Image Quality Metrics (Histogram, MSE, PSNR)
166    // -----------------------------------------------------------------------------------------
167    println!("\n--- 6. Image Metrics: 2D Histogram, MSE, and PSNR ---");
168    let mut hist_bins = [0usize; 5]; // 5 bins covering range 0.0 .. 50.0
169    histogram_2d_f32(&raw_image, &mut hist_bins, 0.0, 50.0);
170    println!(
171        "  2D Image Intensity Histogram (5 bins across 0..50): {:?}",
172        hist_bins
173    );
174
175    let mse = mse_2d_f32(&raw_image, &median_cleaned);
176    let psnr = psnr_2d_f32(&raw_image, &median_cleaned, 50.0);
177    println!("  Raw Noisy vs Median Cleaned Image:");
178    println!("    • Mean Squared Error (MSE)       : {:.2}", mse);
179    println!("    • Peak Signal-to-Noise Ratio (PSNR): {:.2} dB", psnr);
180
181    // -----------------------------------------------------------------------------------------
182    // 7. Q16.16 Fixed-Point Rasterizer & Scanline Interpolation
183    // -----------------------------------------------------------------------------------------
184    println!("\n--- 7. Q16.16 Fixed-Point Scanline Interpolation (MCU Graphics / Rasterizer) ---");
185    // Span of 10 pixels across scanline
186    let span = 10;
187    // Left endpoint: Depth z = 1.0 (Q16.16 = 65536), Texture u = 0.0, v = 0.0
188    // Right endpoint: Depth z = 5.0 (Q16.16 = 327680), Texture u = 1.0 (65536), v = 1.0 (65536)
189    let left_z = to_q16(1.0) as u32;
190    let right_z = to_q16(5.0) as u32;
191    let left_u = to_q16(0.0) as u32;
192    let right_u = to_q16(1.0) as u32;
193    let left_v = to_q16(0.0) as u32;
194    let right_v = to_q16(1.0) as u32;
195
196    let mut scanline = ScanlineInterp::new(left_z, right_z, left_u, right_u, left_v, right_v, span);
197
198    println!("  Interpolating 10 Pixels Across Fixed-Point Scanline (Q16.16):");
199    println!(
200        "    {:<5} {:<12} {:<12} {:<12}",
201        "Pixel", "Depth (z)", "Texcoord (u)", "Texcoord (v)"
202    );
203    println!("    --------------------------------------------------");
204
205    for px in 0..=span {
206        let z_val = from_q16(scanline.z() as i32);
207        let u_val = from_q16(scanline.u() as i32);
208        let v_val = from_q16(scanline.v() as i32);
209
210        if px == 0 || px == 5 || px == span {
211            println!(
212                "    {:<5} {:<12.3} {:<12.3} {:<12.3}",
213                px, z_val, u_val, v_val
214            );
215        }
216        scanline.step();
217    }
218
219    // Fixed-Point arithmetic helpers
220    let a_q16 = to_q16(3.5);
221    let b_q16 = to_q16(2.0);
222    let prod_q16 = mul_q16(a_q16, b_q16);
223    let div_res_q16 = div_q16(a_q16, b_q16);
224    let lerp_res_q16 = lerp_q16(a_q16, b_q16, 5, 10);
225
226    println!("\n  Q16.16 Arithmetic Verification:");
227    println!(
228        "    • mul_q16(3.5, 2.0)   = {:.3} (expected 7.000)",
229        from_q16(prod_q16)
230    );
231    println!(
232        "    • div_q16(3.5, 2.0)   = {:.3} (expected 1.750)",
233        from_q16(div_res_q16)
234    );
235    println!(
236        "    • lerp_q16(3.5, 2.0)  = {:.3} (expected 2.750)",
237        from_q16(lerp_res_q16)
238    );
239
240    println!();
241    println!("===============================================================================");
242    println!("             2D Spatial & Vision Pipeline Execution Complete!                  ");
243    println!("===============================================================================");
244}
Source

pub fn step(&mut self)

Advance all interpolators by one pixel.

Examples found in repository?
examples/spatial_vision_processing.rs (line 216)
25fn main() {
26    println!("===============================================================================");
27    println!("        embedded-dsp 2D Spatial Processing & Embedded Vision                   ");
28    println!("===============================================================================");
29    println!();
30
31    // -----------------------------------------------------------------------------------------
32    // 1. Synthetic 8x8 Sensor Matrix with Block Feature & Salt-and-Pepper Noise
33    // -----------------------------------------------------------------------------------------
34    println!("--- 1. Synthetic 8x8 Image Matrix with Feature & Noise ---");
35    let mut raw_image = [0.0f32; 64];
36
37    // Create a 4x4 high-intensity square in the center
38    for r in 2..6 {
39        for c in 2..6 {
40            raw_image[r * 8 + c] = 20.0;
41        }
42    }
43
44    // Add salt-and-pepper impulsive noise pixels
45    raw_image[1] = 50.0; // Salt noise
46    raw_image[15] = 50.0; // Salt noise
47    raw_image[3 * 8 + 3] = 0.0; // Pepper noise inside feature
48    raw_image[6 * 8 + 2] = 50.0; // Salt noise
49
50    print_matrix_8x8("Raw 8x8 Sensor Image", &raw_image);
51
52    // -----------------------------------------------------------------------------------------
53    // 2. 2D Spatial Convolution (Gaussian Blur & Sharpening)
54    // -----------------------------------------------------------------------------------------
55    println!("\n--- 2. 2D Spatial Convolution (Smoothing & Sharpening) ---");
56    // 3x3 Gaussian Blur Kernel
57    let gaussian_kernel: [f32; 9] = [1.0, 2.0, 1.0, 2.0, 4.0, 2.0, 1.0, 2.0, 1.0];
58    let mut blurred_image = [0.0f32; 64];
59    let status = convolve2d_f32(
60        &raw_image,
61        &mut blurred_image,
62        8,
63        8,
64        &gaussian_kernel,
65        3,
66        3,
67        true,
68    );
69    println!("  Gaussian 3x3 Convolution Status: {:?}", status);
70    print_matrix_8x8("Gaussian Filtered Image (Smoothed)", &blurred_image);
71
72    // 3x3 Sharpening Kernel
73    let sharpen_kernel: [f32; 9] = [0.0, -1.0, 0.0, -1.0, 5.0, -1.0, 0.0, -1.0, 0.0];
74    let mut sharpened_image = [0.0f32; 64];
75    convolve2d_f32(
76        &blurred_image,
77        &mut sharpened_image,
78        8,
79        8,
80        &sharpen_kernel,
81        3,
82        3,
83        false,
84    );
85    print_matrix_8x8("Sharpened Image", &sharpened_image);
86
87    // -----------------------------------------------------------------------------------------
88    // 3. Non-Linear 2D Filtering (Min, Max, Median Despeckling)
89    // -----------------------------------------------------------------------------------------
90    println!("\n--- 3. Non-Linear 2D Filtering (Despeckling & Morphological Filters) ---");
91    let mut median_cleaned = [0.0f32; 64];
92    let mut min_filtered = [0.0f32; 64];
93    let mut max_filtered = [0.0f32; 64];
94
95    // 3x3 Median filter removes impulsive salt & pepper noise while preserving sharp boundaries
96    nonlin2d_filter_f32(
97        &raw_image,
98        &mut median_cleaned,
99        8,
100        8,
101        3,
102        NonlinFilterType::Median,
103    );
104    print_matrix_8x8("3x3 Median Filtered Image (Noise Removed)", &median_cleaned);
105
106    // Morphological erosion (Min) and dilation (Max)
107    nonlin2d_filter_f32(
108        &median_cleaned,
109        &mut min_filtered,
110        8,
111        8,
112        3,
113        NonlinFilterType::Min,
114    );
115    nonlin2d_filter_f32(
116        &median_cleaned,
117        &mut max_filtered,
118        8,
119        8,
120        3,
121        NonlinFilterType::Max,
122    );
123    println!("  Morphological Erosion (Min) & Dilation (Max) computed successfully.");
124
125    // -----------------------------------------------------------------------------------------
126    // 4. 2D Sobel Edge Detection
127    // -----------------------------------------------------------------------------------------
128    println!("\n--- 4. 2D Sobel Edge Detection (Horizontal + Vertical Gradients) ---");
129    let mut edges = [0.0f32; 64];
130    // Threshold set to 15.0 to detect the boundaries of the central block
131    sobel_edge_detection_f32(&median_cleaned, &mut edges, 8, 8, 15.0);
132    print_matrix_8x8(
133        "Sobel Binary Edge Map (1.0 = Edge, 0.0 = Background)",
134        &edges,
135    );
136
137    // -----------------------------------------------------------------------------------------
138    // 5. 2D DCT-II Transform & Energy Compaction (JPEG Block Transform)
139    // -----------------------------------------------------------------------------------------
140    println!("\n--- 5. 2D Discrete Cosine Transform (DCT-II) & Inverse DCT-II ---");
141    let mut dct_coeffs = [0.0f32; 64];
142    let mut reconstructed_image = [0.0f32; 64];
143
144    dct2d_f32(&median_cleaned, &mut dct_coeffs, 8, 8);
145    println!(
146        "  2D DCT DC Coefficient (Top-Left Energy) = {:.2}",
147        dct_coeffs[0]
148    );
149    println!("  Top 2x2 Low-Frequency DCT Coefficients:");
150    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[0], dct_coeffs[1]);
151    println!("    [{:>7.2}, {:>7.2}]", dct_coeffs[8], dct_coeffs[9]);
152
153    // Reconstruct via 2D IDCT
154    idct2d_f32(&dct_coeffs, &mut reconstructed_image, 8, 8);
155    let mut recon_diff = 0.0f32;
156    for i in 0..64 {
157        recon_diff += (reconstructed_image[i] - median_cleaned[i]).abs();
158    }
159    println!(
160        "  2D IDCT Exact Reconstruction Absolute Error Sum: {:.2e}",
161        recon_diff
162    );
163
164    // -----------------------------------------------------------------------------------------
165    // 6. Quantitative Image Quality Metrics (Histogram, MSE, PSNR)
166    // -----------------------------------------------------------------------------------------
167    println!("\n--- 6. Image Metrics: 2D Histogram, MSE, and PSNR ---");
168    let mut hist_bins = [0usize; 5]; // 5 bins covering range 0.0 .. 50.0
169    histogram_2d_f32(&raw_image, &mut hist_bins, 0.0, 50.0);
170    println!(
171        "  2D Image Intensity Histogram (5 bins across 0..50): {:?}",
172        hist_bins
173    );
174
175    let mse = mse_2d_f32(&raw_image, &median_cleaned);
176    let psnr = psnr_2d_f32(&raw_image, &median_cleaned, 50.0);
177    println!("  Raw Noisy vs Median Cleaned Image:");
178    println!("    • Mean Squared Error (MSE)       : {:.2}", mse);
179    println!("    • Peak Signal-to-Noise Ratio (PSNR): {:.2} dB", psnr);
180
181    // -----------------------------------------------------------------------------------------
182    // 7. Q16.16 Fixed-Point Rasterizer & Scanline Interpolation
183    // -----------------------------------------------------------------------------------------
184    println!("\n--- 7. Q16.16 Fixed-Point Scanline Interpolation (MCU Graphics / Rasterizer) ---");
185    // Span of 10 pixels across scanline
186    let span = 10;
187    // Left endpoint: Depth z = 1.0 (Q16.16 = 65536), Texture u = 0.0, v = 0.0
188    // Right endpoint: Depth z = 5.0 (Q16.16 = 327680), Texture u = 1.0 (65536), v = 1.0 (65536)
189    let left_z = to_q16(1.0) as u32;
190    let right_z = to_q16(5.0) as u32;
191    let left_u = to_q16(0.0) as u32;
192    let right_u = to_q16(1.0) as u32;
193    let left_v = to_q16(0.0) as u32;
194    let right_v = to_q16(1.0) as u32;
195
196    let mut scanline = ScanlineInterp::new(left_z, right_z, left_u, right_u, left_v, right_v, span);
197
198    println!("  Interpolating 10 Pixels Across Fixed-Point Scanline (Q16.16):");
199    println!(
200        "    {:<5} {:<12} {:<12} {:<12}",
201        "Pixel", "Depth (z)", "Texcoord (u)", "Texcoord (v)"
202    );
203    println!("    --------------------------------------------------");
204
205    for px in 0..=span {
206        let z_val = from_q16(scanline.z() as i32);
207        let u_val = from_q16(scanline.u() as i32);
208        let v_val = from_q16(scanline.v() as i32);
209
210        if px == 0 || px == 5 || px == span {
211            println!(
212                "    {:<5} {:<12.3} {:<12.3} {:<12.3}",
213                px, z_val, u_val, v_val
214            );
215        }
216        scanline.step();
217    }
218
219    // Fixed-Point arithmetic helpers
220    let a_q16 = to_q16(3.5);
221    let b_q16 = to_q16(2.0);
222    let prod_q16 = mul_q16(a_q16, b_q16);
223    let div_res_q16 = div_q16(a_q16, b_q16);
224    let lerp_res_q16 = lerp_q16(a_q16, b_q16, 5, 10);
225
226    println!("\n  Q16.16 Arithmetic Verification:");
227    println!(
228        "    • mul_q16(3.5, 2.0)   = {:.3} (expected 7.000)",
229        from_q16(prod_q16)
230    );
231    println!(
232        "    • div_q16(3.5, 2.0)   = {:.3} (expected 1.750)",
233        from_q16(div_res_q16)
234    );
235    println!(
236        "    • lerp_q16(3.5, 2.0)  = {:.3} (expected 2.750)",
237        from_q16(lerp_res_q16)
238    );
239
240    println!();
241    println!("===============================================================================");
242    println!("             2D Spatial & Vision Pipeline Execution Complete!                  ");
243    println!("===============================================================================");
244}
Source

pub fn step_n(&mut self, n: i32)

Advance n pixels at once (useful for skipping clipped scanline segments).

Source

pub fn z_f32(&self) -> f32

Current depth as f32.

Trait Implementations§

Source§

impl Clone for ScanlineInterp

Source§

fn clone(&self) -> ScanlineInterp

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for ScanlineInterp

Source§

impl Debug for ScanlineInterp

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Az for T

Source§

fn az<Dst>(self) -> Dst
where T: Cast<Dst>,

Casts the value.
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<Src, Dst> CastFrom<Src> for Dst
where Src: Cast<Dst>,

Source§

fn cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CheckedAs for T

Source§

fn checked_as<Dst>(self) -> Option<Dst>
where T: CheckedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> CheckedCastFrom<Src> for Dst
where Src: CheckedCast<Dst>,

Source§

fn checked_cast_from(src: Src) -> Option<Dst>

Casts the value.
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<Src, Dst> LosslessTryInto<Dst> for Src
where Dst: LosslessTryFrom<Src>,

Source§

fn lossless_try_into(self) -> Option<Dst>

Performs the conversion.
Source§

impl<Src, Dst> LossyInto<Dst> for Src
where Dst: LossyFrom<Src>,

Source§

fn lossy_into(self) -> Dst

Performs the conversion.
Source§

impl<T> OverflowingAs for T

Source§

fn overflowing_as<Dst>(self) -> (Dst, bool)
where T: OverflowingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> OverflowingCastFrom<Src> for Dst
where Src: OverflowingCast<Dst>,

Source§

fn overflowing_cast_from(src: Src) -> (Dst, bool)

Casts the value.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> SaturatingAs for T

Source§

fn saturating_as<Dst>(self) -> Dst
where T: SaturatingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> SaturatingCastFrom<Src> for Dst
where Src: SaturatingCast<Dst>,

Source§

fn saturating_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> StrictAs for T

Source§

fn strict_as<Dst>(self) -> Dst
where T: StrictCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> StrictCastFrom<Src> for Dst
where Src: StrictCast<Dst>,

Source§

fn strict_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> UnwrappedAs for T

Source§

fn unwrapped_as<Dst>(self) -> Dst
where T: UnwrappedCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> UnwrappedCastFrom<Src> for Dst
where Src: UnwrappedCast<Dst>,

Source§

fn unwrapped_cast_from(src: Src) -> Dst

Casts the value.
Source§

impl<T> WrappingAs for T

Source§

fn wrapping_as<Dst>(self) -> Dst
where T: WrappingCast<Dst>,

Casts the value.
Source§

impl<Src, Dst> WrappingCastFrom<Src> for Dst
where Src: WrappingCast<Dst>,

Source§

fn wrapping_cast_from(src: Src) -> Dst

Casts the value.