Move Bresenham line drawing into library from Hough example

This commit is contained in:
cdo committed 2026-10-29 10:48:33 +00:00
1 parent fd9b027eea
commit d550a7e71e
3 files changed
+60 -72

No files matched your search

+16 -72
View File
@@ -1,10 +1,8 @@
mod common;
use ccvl::filter::*;
use ccvl::hough;
use ccvl::image::*;
use ccvl::*;
const LINE: SRGBA = SRGBA {
const LINE: image::SRGBA = image::SRGBA {
r: 1.0,
g: 0.0,
b: 0.0,
@@ -13,25 +11,25 @@ const LINE: SRGBA = SRGBA {
fn main() -> std::process::ExitCode {
common::process_image(|mut img| {
let greyscale = img.map(|p| Luminance::from(p));
let edges = canny(greyscale);
let greyscale = img.map(|p| image::Luminance::from(p));
let edges = filter::canny(greyscale);
for line in hough::lines(10.0, edges) {
draw(line, &mut img);
let ((x0, y0), (x1, y1)) = endpoints(line, img.extent);
draw::line(x0, y0, x1, y1, &mut img, LINE);
}
img
})
}
fn in_bounds(q: &(f32, f32), lim: Extent) -> bool {
let x_in = 0.0 <= q.0 && q.0 < lim.x as f32;
let y_in = 0.0 <= q.1 && q.1 < lim.y as f32;
x_in && y_in
}
fn endpoints(
l: hough::Line,
lim: Extent,
lim: image::Extent,
) -> ((usize, usize), (usize, usize)) {
if l.theta.abs() < 1e-3 {
((l.rho as usize, 0), (l.rho as usize, lim.y - 1))
} else if l.theta - std::f32::consts::PI / 2.0 < 1e-3 {
((0, l.rho as usize), (lim.x - 1, l.rho as usize))
} else {
let w = lim.x as f32 - 1e-3;
let h = lim.y as f32 - 1e-3;
@@ -51,64 +49,10 @@ fn endpoints(
}
(res[0], res[1])
}
fn draw(l: hough::Line, img: &mut Image<SRGBA>) {
if l.theta.abs() < 1e-3 {
// vertical line
let x = l.rho as usize;
for y in 0..img.extent.y {
if x >= img.extent.x || y >= img.extent.y {
return;
}
*img.at_mut(x, y) = LINE;
}
} else if (l.theta - std::f32::consts::PI / 2.0) < 1e-3 {
// horizontal line
let y = l.rho as usize;
for x in 0..img.extent.x {
if x >= img.extent.x || y >= img.extent.y {
return;
}
*img.at_mut(x, y) = LINE;
}
} else {
bresenham(endpoints(l, img.extent), img);
}
}
fn bresenham(qs: ((usize, usize), (usize, usize)), img: &mut Image<SRGBA>) {
let ((x0, y0), (x1, y1)) = qs;
let dx = x0.abs_diff(x1) as isize;
let dy = -(y0.abs_diff(y1) as isize);
let sx = if x0 < x1 { 1 } else { -1 };
let sy = if y0 < y1 { 1 } else { -1 };
let mut x = x0;
let mut y = y0;
let mut error = dx + dy;
loop {
if x >= img.extent.x || y >= img.extent.y {
return;
}
*img.at_mut(x, y) = LINE;
let e2 = 2 * error;
if e2 >= dy {
if x == x1 {
break;
}
error += dy;
x = (x as isize + sx) as usize;
}
if e2 <= dx {
if y == y1 {
break;
}
error += dx;
y = (y as isize + sy) as usize;
}
}
fn in_bounds(q: &(f32, f32), lim: image::Extent) -> bool {
let x_in = 0.0 <= q.0 && q.0 < lim.x as f32;
let y_in = 0.0 <= q.1 && q.1 < lim.y as f32;
x_in && y_in
}
+43
View File
@@ -0,0 +1,43 @@
use crate::*;
pub fn line<P: Copy>(
x0: usize,
y0: usize,
x1: usize,
y1: usize,
img: &mut image::Image<P>,
colour: P,
) {
let dx = x0.abs_diff(x1) as isize;
let dy = -(y0.abs_diff(y1) as isize);
let sx = if x0 < x1 { 1 } else { -1 };
let sy = if y0 < y1 { 1 } else { -1 };
let mut x = x0;
let mut y = y0;
let mut error = dx + dy;
loop {
if x >= img.extent.x || y >= img.extent.y {
return;
}
*img.at_mut(x, y) = colour;
let e2 = 2 * error;
if e2 >= dy {
if x == x1 {
break;
}
error += dy;
x = (x as isize + sx) as usize;
}
if e2 <= dx {
if y == y1 {
break;
}
error += dx;
y = (y as isize + sy) as usize;
}
}
}
+1
View File
@@ -1,4 +1,5 @@
pub mod contour;
pub mod draw;
pub mod filter;
pub mod hough;
pub mod image;