Skip to content

Commit 9613a5a

Browse files
authored
Merge pull request #540 from KmolYuan/dashed-fix
Fix dashed line algorithm
2 parents 3a4c675 + 698f8ca commit 9613a5a

File tree

2 files changed

+35
-27
lines changed

2 files changed

+35
-27
lines changed

plotters/src/element/basic_shapes.rs

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -188,35 +188,43 @@ impl<I0: Iterator + Clone, Size: SizeDesc, DB: DrawingBackend> Drawable<DB>
188188
None => return Ok(()),
189189
};
190190
let size = self.size.in_pixels(&ps).max(0) as f32;
191+
if size == 0. {
192+
return Ok(());
193+
}
191194
let spacing = self.spacing.in_pixels(&ps).max(0) as f32;
192195
let mut dist = 0.;
193196
let mut is_solid = true;
194197
let mut queue = vec![to_i(start)];
195198
for curr in points {
196-
let curr_f = to_f(curr);
197-
let (dx, dy) = (curr_f.0 - start.0, curr_f.1 - start.1);
198-
let d = dx.hypot(dy).max(f32::EPSILON);
199-
dist += d;
200-
if is_solid {
201-
if dist < size {
202-
queue.push(curr);
203-
start = curr_f;
204-
} else {
205-
let t = (dist - size) / d;
199+
let end = to_f(curr);
200+
// Loop for solid and spacing
201+
while start != end {
202+
let (dx, dy) = (end.0 - start.0, end.1 - start.1);
203+
let d = dx.hypot(dy);
204+
let size = if is_solid { size } else { spacing };
205+
let left = size - dist;
206+
// Set next point to `start`
207+
if left < d {
208+
let t = left / d;
206209
start = (start.0 + dx * t, start.1 + dy * t);
210+
dist += left;
211+
} else {
212+
start = end;
213+
dist += d;
214+
}
215+
// Draw if needed
216+
if is_solid {
207217
queue.push(to_i(start));
208-
backend.draw_path(queue.drain(..), &self.style)?;
218+
}
219+
if size <= dist {
220+
if is_solid {
221+
backend.draw_path(queue.drain(..), &self.style)?;
222+
} else {
223+
queue.push(to_i(start));
224+
}
209225
dist = 0.;
210-
is_solid = false;
226+
is_solid = !is_solid;
211227
}
212-
} else if dist < spacing {
213-
start = curr_f;
214-
} else {
215-
let t = (dist - spacing) / d;
216-
start = (start.0 + dx * t, start.1 + dy * t);
217-
queue.push(to_i(start));
218-
dist = 0.;
219-
is_solid = true;
220228
}
221229
}
222230
if queue.len() > 1 {
@@ -231,9 +239,9 @@ impl<I0: Iterator + Clone, Size: SizeDesc, DB: DrawingBackend> Drawable<DB>
231239
fn test_dashed_path_element() {
232240
use crate::prelude::*;
233241
let check_list = std::cell::RefCell::new(vec![
234-
vec![(100, 100), (100, 103), (100, 118)],
235-
vec![(100, 105), (100, 110)],
236-
vec![(100, 112), (100, 117)],
242+
vec![(100, 100), (100, 103), (100, 105)],
243+
vec![(100, 107), (100, 112)],
244+
vec![(100, 114), (100, 119)],
237245
vec![(100, 119), (100, 120)],
238246
]);
239247
let da = crate::create_mocked_drawing_area(300, 300, |m| {
@@ -243,8 +251,8 @@ fn test_dashed_path_element() {
243251
assert_eq!(path, check_list.borrow_mut().remove(0));
244252
});
245253
m.drop_check(|b| {
246-
assert_eq!(b.num_draw_path_call, 1);
247-
assert_eq!(b.draw_count, 1);
254+
assert_eq!(b.num_draw_path_call, 3);
255+
assert_eq!(b.draw_count, 3);
248256
});
249257
});
250258
da.draw(&DashedPathElement::new(

plotters/src/series/line_series.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ mod test {
144144
});
145145

146146
m.drop_check(|b| {
147-
assert_eq!(b.num_draw_path_call, 9);
148-
assert_eq!(b.draw_count, 9);
147+
assert_eq!(b.num_draw_path_call, 8);
148+
assert_eq!(b.draw_count, 8);
149149
});
150150
});
151151

0 commit comments

Comments
 (0)