use crate::{
geometry::Dimensions,
primitives::{
common::{LineJoin, Scanline},
Line, Rectangle,
},
};
#[derive(Debug, Clone, Copy)]
pub struct ThickSegment {
start_join: LineJoin,
end_join: LineJoin,
}
impl ThickSegment {
pub const fn new(start_join: LineJoin, end_join: LineJoin) -> Self {
Self {
start_join,
end_join,
}
}
pub fn is_skeleton(&self) -> bool {
self.start_join.first_edge_end.left == self.start_join.first_edge_end.right
}
const fn edges(&self) -> (Line, Line) {
(
Line::new(
self.start_join.second_edge_start.right,
self.end_join.first_edge_end.right,
),
Line::new(
self.end_join.first_edge_end.left,
self.start_join.second_edge_start.left,
),
)
}
pub fn edges_bounding_box(&self) -> Rectangle {
let (right, left) = self.edges();
if self.is_skeleton() {
return left.bounding_box();
}
Rectangle::with_corners(
right
.start
.component_min(right.end)
.component_min(left.start)
.component_min(left.end),
right
.start
.component_max(right.end)
.component_max(left.start)
.component_max(left.end),
)
}
pub fn intersection(&self, scanline_y: i32) -> Scanline {
let mut scanline = Scanline::new_empty(scanline_y);
if self.is_skeleton() {
scanline.bresenham_intersection(&self.edges().0);
} else {
let (line1, line2) = self.start_join.start_cap_lines();
scanline.bresenham_intersection(&line1);
if let Some(line2) = line2 {
scanline.bresenham_intersection(&line2);
}
let (line1, line2) = self.end_join.end_cap_lines();
scanline.bresenham_intersection(&line1);
if let Some(line2) = line2 {
scanline.bresenham_intersection(&line2);
}
let (line1, line2) = self.edges();
scanline.bresenham_intersection(&line1);
scanline.bresenham_intersection(&line2);
}
scanline
}
}