Implement Bezier curve reduce function (#711)

* fixed extrema bug and added reduce impl

Co-authored-by: Rob Nadal <RobNadal@users.noreply.github.com>
Co-authored-by: Linda Zheng <ll2zheng@uwaterloo.ca>
Co-authored-by: Hannah Li <hannahli2010@gmail.com>

* Stylistic changes related to reduce

* Fixed reduce splitting bug causing panic

* Added shortcuts and simplified reduce

* Stylistic changes per review

* address comments

* Removed color gradient function and added consts

* Tweaks

* Change colors faster

* Don't drop on mouseout

Co-authored-by: Thomas Cheng <contact.chengthomas@gmail.com>
Co-authored-by: Rob Nadal <RobNadal@users.noreply.github.com>
Co-authored-by: Linda Zheng <ll2zheng@uwaterloo.ca>
Co-authored-by: Hannah Li <hannahli2010@gmail.com>
Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Rob Nadal
2022-07-06 11:20:28 -07:00
committed by GitHub
co-authored by Rob Nadal Linda Zheng Hannah Li Thomas Cheng Keavon Chambers
parent f3d5028107
commit b4ada6affd
7 changed files with 142 additions and 18 deletions
@@ -15,10 +15,20 @@ struct Point {
pub struct WasmBezier(Bezier);
/// Convert a `DVec2` into a `JsValue`.
pub fn vec_to_point(p: &DVec2) -> JsValue {
fn vec_to_point(p: &DVec2) -> JsValue {
JsValue::from_serde(&serde_json::to_string(&Point { x: p.x, y: p.y }).unwrap()).unwrap()
}
/// Convert a bezier to a list of points.
fn bezier_to_points(bezier: Bezier) -> Vec<Point> {
bezier.get_points().iter().flatten().map(|point| Point { x: point.x, y: point.y }).collect()
}
/// Serialize some data and then convert it to a JsValue.
fn to_js_value<T: Serialize>(data: T) -> JsValue {
JsValue::from_serde(&serde_json::to_string(&data).unwrap()).unwrap()
}
#[wasm_bindgen]
impl WasmBezier {
/// Expect js_points to be a list of 3 pairs.
@@ -88,11 +98,8 @@ impl WasmBezier {
}
pub fn split(&self, t: f64) -> JsValue {
let bezier_points: [Vec<Point>; 2] = self
.0
.split(t)
.map(|bezier| bezier.get_points().iter().flatten().map(|point| Point { x: point.x, y: point.y }).collect());
JsValue::from_serde(&serde_json::to_string(&bezier_points).unwrap()).unwrap()
let bezier_points: [Vec<Point>; 2] = self.0.split(t).map(bezier_to_points);
to_js_value(bezier_points)
}
pub fn trim(&self, t1: f64, t2: f64) -> WasmBezier {
@@ -105,7 +112,7 @@ impl WasmBezier {
pub fn local_extrema(&self) -> JsValue {
let local_extrema = self.0.local_extrema();
JsValue::from_serde(&serde_json::to_string(&local_extrema).unwrap()).unwrap()
to_js_value(local_extrema)
}
pub fn rotate(&self, angle: f64) -> WasmBezier {
@@ -116,4 +123,9 @@ impl WasmBezier {
let line: [DVec2; 2] = js_points.into_serde().unwrap();
self.0.intersect_line_segment(line).iter().map(|&p| vec_to_point(&p)).collect::<Vec<JsValue>>()
}
pub fn reduce(&self) -> JsValue {
let bezier_points: Vec<Vec<Point>> = self.0.reduce(None).into_iter().map(bezier_to_points).collect();
to_js_value(bezier_points)
}
}