Speed up fractal_clock painting (#152)

clip unwatchable line before drawing
This commit is contained in:
xue-blood 2021-02-06 23:59:46 +08:00 committed by GitHub
parent 26f966563a
commit ce14fa860b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 2 deletions

View File

@ -116,6 +116,9 @@ impl Painter {
.add(self.clip_rect, shape)
}
/// Add many shapes at once.
///
/// Calling this once is generally faster than calling [`Self::add`] multiple times.
pub fn extend(&self, shapes: Vec<Shape>) {
if !shapes.is_empty() {
self.ctx

View File

@ -13,6 +13,7 @@ pub struct FractalClock {
length_factor: f32,
luminance_factor: f32,
width_factor: f32,
line_count: usize,
}
impl Default for FractalClock {
@ -26,6 +27,7 @@ impl Default for FractalClock {
length_factor: 0.8,
luminance_factor: 0.8,
width_factor: 0.9,
line_count: 0,
}
}
}
@ -79,6 +81,7 @@ impl FractalClock {
} else {
ui.label("The fractal_clock clock is not showing the correct time");
};
ui.label(format!("Painted line count: {}", self.line_count));
ui.checkbox(&mut self.paused, "Paused");
ui.add(Slider::f32(&mut self.zoom, 0.0..=1.0).text("zoom"));
@ -128,13 +131,16 @@ impl FractalClock {
];
let scale = self.zoom * rect.width().min(rect.height());
let paint_line = |points: [Pos2; 2], color: Color32, width: f32| {
let mut shapes: Vec<Shape> = Vec::new();
let mut paint_line = |points: [Pos2; 2], color: Color32, width: f32| {
let line = [
rect.center() + scale * points[0].to_vec2(),
rect.center() + scale * points[1].to_vec2(),
];
painter.line_segment([line[0], line[1]], (width, color));
if rect.intersects(Rect::from_two_pos(line[0], line[1])) {
shapes.push(Shape::line_segment(line, (width, color)));
}
};
let hand_rotations = [
@ -199,5 +205,7 @@ impl FractalClock {
std::mem::swap(&mut nodes, &mut new_nodes);
}
self.line_count = shapes.len();
painter.extend(shapes);
}
}

View File

@ -91,6 +91,14 @@ impl Rect {
max: pos2(*x_range.end(), *y_range.end()),
}
}
pub fn from_two_pos(a: Pos2, b: Pos2) -> Self {
let (left, right) = if a.x > b.x { (b.x, a.x) } else { (a.x, b.x) };
let (top, bottom) = if a.y > b.y { (b.y, a.y) } else { (a.y, b.y) };
Rect {
min: pos2(left, top),
max: pos2(right, bottom),
}
}
/// Expand by this much in each direction, keeping the center
#[must_use]