del_canvas/rasterize/
line2.rs1use num_traits::AsPrimitive;
2
3pub fn draw_dda_pixel_coordinate<Real, VAL>(
5 img_data: &mut [VAL],
6 width: usize,
7 p0: &[Real; 2],
8 p1: &[Real; 2],
9 i_color: VAL,
10) where
11 Real: num_traits::Float + 'static + AsPrimitive<usize> + std::fmt::Debug,
12 usize: AsPrimitive<Real>,
13 VAL: Copy,
14{
15 let height = img_data.len() / width;
16 let width_f: Real = width.as_();
17 let height_f: Real = height.as_();
18 let zero = Real::zero();
19 let dx = p1[0] - p0[0];
20 let dy = p1[1] - p0[1];
21 let step = if dx.abs() > dy.abs() {
22 dx.abs()
23 } else {
24 dy.abs()
25 };
26 let slope_y = dy / step;
27 let slope_x = dx / step;
28 let mut x = p0[0];
29 let mut y = p0[1];
30 while (x - p0[0]).abs() <= (p1[0] - p0[0]).abs() && (y - p0[1]).abs() <= (p1[1] - p0[1]).abs() {
31 if x >= zero && x < width_f && y >= zero && y < height_f {
32 let ix: usize = x.as_();
33 let iy: usize = y.as_();
34 img_data[iy * width + ix] = i_color;
35 }
36 x = x + slope_x;
37 y = y + slope_y;
38 }
39}
40
41pub fn draw_dda<Real, VAL>(
43 img_data: &mut [VAL],
44 width: usize,
45 p0: &[Real; 2],
46 p1: &[Real; 2],
47 transform: &[Real; 9],
48 i_color: VAL,
49) where
50 Real: num_traits::Float + std::fmt::Debug + 'static + AsPrimitive<usize>,
51 usize: AsPrimitive<Real>,
52 VAL: Copy,
53{
54 let q0 = del_geo_core::mat3_col_major::transform_homogeneous(transform, p0).unwrap();
55 let q1 = del_geo_core::mat3_col_major::transform_homogeneous(transform, p1).unwrap();
56 draw_dda_pixel_coordinate(img_data, width, &q0, &q1, i_color);
57}
58
59pub fn pixels_in_line<Real>(
60 x0: Real,
61 y0: Real,
62 x1: Real,
63 y1: Real,
64 rad: Real,
65 width: usize,
66 height: usize,
67) -> Vec<usize>
68where
69 Real: num_traits::Float + 'static + AsPrimitive<usize>,
70 usize: AsPrimitive<Real>,
71{
72 let half: Real = Real::one() / (Real::one() + Real::one());
73 let aabbi = {
74 let aabb = del_geo_core::aabb2::from_two_points(&[x0, y0], &[x1, y1], rad);
75 del_geo_core::aabb2::rasterize(&aabb, &(width, height))
76 };
77 let sqlen = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
78 let mut res = Vec::<usize>::new();
79 for ih in aabbi[1]..aabbi[3] {
80 for iw in aabbi[0]..aabbi[2] {
81 let w: Real = iw.as_() + half; let h: Real = ih.as_() + half; let t = ((w - x0) * (x1 - x0) + (h - y0) * (y1 - y0)) / sqlen;
84 let sqdist = if t < Real::zero() {
85 (w - x0) * (w - x0) + (h - y0) * (h - y0)
86 } else if t > Real::one() {
87 (w - x1) * (w - x1) + (h - y1) * (h - y1)
88 } else {
89 (w - x0) * (w - x0) + (h - y0) * (h - y0) - sqlen * t * t
90 };
91 if sqdist > rad * rad {
92 continue;
93 }
94 res.push(ih * width + iw);
95 }
96 }
97 res
98}
99
100pub fn draw_pixcenter<T, VAL>(
102 img_data: &mut [VAL],
103 width: usize,
104 p0: &[T; 2],
105 p1: &[T; 2],
106 transform_world2pix: &[T; 9],
107 thickness: T,
108 color: VAL,
109) where
110 T: num_traits::Float + num_traits::AsPrimitive<usize>,
111 usize: AsPrimitive<T>,
112 VAL: Copy,
113{
114 let height = img_data.len() / width;
115 let a0 = del_geo_core::mat3_col_major::transform_homogeneous(transform_world2pix, p0).unwrap();
116 let a1 = del_geo_core::mat3_col_major::transform_homogeneous(transform_world2pix, p1).unwrap();
117 let pixs = pixels_in_line(a0[0], a0[1], a1[0], a1[1], thickness, width, height);
118 for i_data in pixs {
119 img_data[i_data] = color;
120 }
121}