1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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
}
}