Skip to content

Commit

Permalink
apply suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
juliapaci committed Aug 7, 2024
1 parent c1b6892 commit 861dd7f
Showing 1 changed file with 59 additions and 36 deletions.
95 changes: 59 additions & 36 deletions src/bezpath.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
use bevy_ecs::prelude::*;
use bevy_math::DVec2;
use bevy_utils::prelude::*;
use bevy_vello::{prelude::*, vello::kurbo::PathEl};
use bevy_vello::{
prelude::*,
vello::kurbo::{PathEl, Point},
};

use super::Vector;

Expand All @@ -13,7 +16,7 @@ pub struct VelloBezPath {
/// Bézier path.
pub path: kurbo::BezPath,
/// Tracing percentage from the start to the end of the entire Bézier path.
pub trace: f32,
pub trace: f64,
}

impl VelloBezPath {
Expand All @@ -26,7 +29,7 @@ impl VelloBezPath {
self
}

pub fn with_trace(mut self, trace: f32) -> Self {
pub fn with_trace(mut self, trace: f64) -> Self {
self.trace = trace;
self
}
Expand Down Expand Up @@ -61,24 +64,24 @@ impl Vector for VelloBezPath {
let mut path = kurbo::BezPath::new();

let pathel_count = pathels.len();
let trace_raw = self.trace * pathel_count as f32;
let trace_raw = self.trace * pathel_count as f64;

let mut most_recent_initial = kurbo::Point::new(0.0, 0.0);
let mut most_recent_point = kurbo::Point::new(0.0, 0.0);

for (path_index, pathel) in pathels.iter().enumerate() {
let mut interp_value = trace_raw - path_index as f32;
let mut interp_value = trace_raw - path_index as f64;

// if interp_value <= 0.0 {
// pathels[path_index] = kurbo::PathEl::MoveTo(kurbo::Point::default());
// } else {
if interp_value > 0.0 {
// Clamp value within 1.0
interp_value = f32::min(interp_value, 1.0);
interp_value = f64::min(interp_value, 1.0);

match pathel {
kurbo::PathEl::MoveTo(p) => {
path.push(kurbo::PathEl::MoveTo(*p));
path.push(PathEl::MoveTo(*p));

most_recent_initial = *p;
most_recent_point = *p;
Expand Down Expand Up @@ -120,7 +123,7 @@ impl Vector for VelloBezPath {
let (path, t) = self.inbetween(time);

let current = path.0.end_point().unwrap_or_default();
let point = interp_pathel(current, path.1, t as f32)
let point = interp_pathel(current, path.1, t)
.end_point()
.unwrap()
.to_vec2();
Expand All @@ -132,55 +135,75 @@ impl Vector for VelloBezPath {
let (path, t) = self.inbetween(time);

let current = path.0.end_point().unwrap_or_default();
let before = interp_pathel(current, path.1, t as f32 - 1e-4)
.end_point()
.unwrap();
let next = interp_pathel(current, path.1, t as f32)
.end_point()
.unwrap()
.to_vec2();

(next - before.to_vec2()).angle()
match path.1 {
PathEl::MoveTo(_) => unreachable!(),
PathEl::ClosePath => unreachable!(),
PathEl::LineTo(p) => (p.to_vec2() - current.to_vec2()).angle(),
PathEl::QuadTo(p1, p2) => {
let a = current.lerp(p1, t);
let b = p1.lerp(p2, t);
(b.y - a.y).atan2(b.x - a.x)
},
PathEl::CurveTo(p1, p2, p3) => {
let a = current.lerp(p1, t);
let b = p1.lerp(p2, t);
let c = p2.lerp(p3, t);

let d = a.lerp(b, t);
let e = b.lerp(c, t);
(d.y - e.y).atan2(d.x - e.x)
},
_ => {
// cant do f64::EPSILON cause of precision issues
let before = interp_pathel(current, path.1, t - f32::EPSILON as f64)
.end_point()
.unwrap();
let next = interp_pathel(current, path.1, t)
.end_point()
.unwrap()
.to_vec2();

(next - before.to_vec2()).angle()
}
}
}
}

/// Interpolate [`kurbo::PathEl`].
fn interp_pathel(p0: kurbo::Point, pathel: kurbo::PathEl, t: f32) -> kurbo::PathEl {
fn interp_pathel(p0: kurbo::Point, pathel: kurbo::PathEl, t: f64) -> kurbo::PathEl {
if t == 1.0 {
return pathel;
}

match pathel {
kurbo::PathEl::MoveTo(p1) => kurbo::PathEl::MoveTo(kurbo::Point::lerp(p0, p1, t as f64)),
kurbo::PathEl::LineTo(p1) => kurbo::PathEl::LineTo(kurbo::Point::lerp(p0, p1, t as f64)),
kurbo::PathEl::QuadTo(p1, p2) => {
let t = t as f64;
PathEl::MoveTo(p1) => kurbo::PathEl::MoveTo(kurbo::Point::lerp(p0, p1, t)),
PathEl::LineTo(p1) => kurbo::PathEl::LineTo(kurbo::Point::lerp(p0, p1, t)),
PathEl::QuadTo(p1, p2) => {
// Point between p0 and p1
let x0 = kurbo::Point::lerp(p0, p1, t);
let x0 = Point::lerp(p0, p1, t);
// Point between p1 and p2
let x1 = kurbo::Point::lerp(p1, p2, t);
let x1 = Point::lerp(p1, p2, t);
// Point on curve
let end_p = kurbo::Point::lerp(x0, x1, t);
let end_p = Point::lerp(x0, x1, t);

kurbo::PathEl::QuadTo(x0, end_p)
PathEl::QuadTo(x0, end_p)
}
kurbo::PathEl::CurveTo(p1, p2, p3) => {
let t = t as f64;
PathEl::CurveTo(p1, p2, p3) => {
// Point between p0 and p1
let x0 = kurbo::Point::lerp(p0, p1, t);
let x0 = Point::lerp(p0, p1, t);
// Point between p1 and p2
let x1 = kurbo::Point::lerp(p1, p2, t);
let x1 = Point::lerp(p1, p2, t);
// Point between p2 and p3
let x2 = kurbo::Point::lerp(p2, p3, t);
let x2 = Point::lerp(p2, p3, t);
// Point between x0 and x1
let y0 = kurbo::Point::lerp(x0, x1, t);
let y0 = Point::lerp(x0, x1, t);
// Point between x1 and x2
let y1 = kurbo::Point::lerp(x1, x2, t);
let y1 = Point::lerp(x1, x2, t);
// Point on curve
let end_p = kurbo::Point::lerp(y0, y1, t);
let end_p = Point::lerp(y0, y1, t);

kurbo::PathEl::CurveTo(x0, y0, end_p)
PathEl::CurveTo(x0, y0, end_p)
}
kurbo::PathEl::ClosePath => kurbo::PathEl::ClosePath,
PathEl::ClosePath => PathEl::ClosePath,
}
}

0 comments on commit 861dd7f

Please sign in to comment.