Skip to content

Commit

Permalink
Merge pull request #540 from KmolYuan/dashed-fix
Browse files Browse the repository at this point in the history
Fix dashed line algorithm
  • Loading branch information
AaronErhardt authored Jan 21, 2024
2 parents 3a4c675 + 698f8ca commit 9613a5a
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 27 deletions.
58 changes: 33 additions & 25 deletions plotters/src/element/basic_shapes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,35 +188,43 @@ impl<I0: Iterator + Clone, Size: SizeDesc, DB: DrawingBackend> Drawable<DB>
None => return Ok(()),
};
let size = self.size.in_pixels(&ps).max(0) as f32;
if size == 0. {
return Ok(());
}
let spacing = self.spacing.in_pixels(&ps).max(0) as f32;
let mut dist = 0.;
let mut is_solid = true;
let mut queue = vec![to_i(start)];
for curr in points {
let curr_f = to_f(curr);
let (dx, dy) = (curr_f.0 - start.0, curr_f.1 - start.1);
let d = dx.hypot(dy).max(f32::EPSILON);
dist += d;
if is_solid {
if dist < size {
queue.push(curr);
start = curr_f;
} else {
let t = (dist - size) / d;
let end = to_f(curr);
// Loop for solid and spacing
while start != end {
let (dx, dy) = (end.0 - start.0, end.1 - start.1);
let d = dx.hypot(dy);
let size = if is_solid { size } else { spacing };
let left = size - dist;
// Set next point to `start`
if left < d {
let t = left / d;
start = (start.0 + dx * t, start.1 + dy * t);
dist += left;
} else {
start = end;
dist += d;
}
// Draw if needed
if is_solid {
queue.push(to_i(start));
backend.draw_path(queue.drain(..), &self.style)?;
}
if size <= dist {
if is_solid {
backend.draw_path(queue.drain(..), &self.style)?;
} else {
queue.push(to_i(start));
}
dist = 0.;
is_solid = false;
is_solid = !is_solid;
}
} else if dist < spacing {
start = curr_f;
} else {
let t = (dist - spacing) / d;
start = (start.0 + dx * t, start.1 + dy * t);
queue.push(to_i(start));
dist = 0.;
is_solid = true;
}
}
if queue.len() > 1 {
Expand All @@ -231,9 +239,9 @@ impl<I0: Iterator + Clone, Size: SizeDesc, DB: DrawingBackend> Drawable<DB>
fn test_dashed_path_element() {
use crate::prelude::*;
let check_list = std::cell::RefCell::new(vec![
vec![(100, 100), (100, 103), (100, 118)],
vec![(100, 105), (100, 110)],
vec![(100, 112), (100, 117)],
vec![(100, 100), (100, 103), (100, 105)],
vec![(100, 107), (100, 112)],
vec![(100, 114), (100, 119)],
vec![(100, 119), (100, 120)],
]);
let da = crate::create_mocked_drawing_area(300, 300, |m| {
Expand All @@ -243,8 +251,8 @@ fn test_dashed_path_element() {
assert_eq!(path, check_list.borrow_mut().remove(0));
});
m.drop_check(|b| {
assert_eq!(b.num_draw_path_call, 1);
assert_eq!(b.draw_count, 1);
assert_eq!(b.num_draw_path_call, 3);
assert_eq!(b.draw_count, 3);
});
});
da.draw(&DashedPathElement::new(
Expand Down
4 changes: 2 additions & 2 deletions plotters/src/series/line_series.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ mod test {
});

m.drop_check(|b| {
assert_eq!(b.num_draw_path_call, 9);
assert_eq!(b.draw_count, 9);
assert_eq!(b.num_draw_path_call, 8);
assert_eq!(b.draw_count, 8);
});
});

Expand Down

0 comments on commit 9613a5a

Please sign in to comment.