Bezier-rs: Add self_intersection to subpath (#1035)

* add self-intersection to subpath, rebased old work onto master

* fix interactive website after rebase

* fix rustdoc iframe placement

* remove double comment

* address comments

* revert evaluate change

* address comment + fix assert statement bug

* update function comments
This commit is contained in:
Thomas Cheng
2023-02-21 17:08:55 -05:00
committed by Keavon Chambers
parent 4797aed05b
commit f2d35f50de
6 changed files with 164 additions and 66 deletions
@@ -179,7 +179,7 @@ impl WasmSubpath {
wrap_svg_tag(content)
}
pub fn intersect_line_segment(&self, js_points: JsValue) -> String {
pub fn intersect_line_segment(&self, js_points: JsValue, error: f64, minimum_separation: f64) -> String {
let points: [DVec2; 2] = serde_wasm_bindgen::from_value(js_points).unwrap();
let line = Bezier::from_linear_dvec2(points[0], points[1]);
@@ -197,10 +197,13 @@ impl WasmSubpath {
let intersections_svg = self
.0
.intersections(&line, None, None)
.intersections(&line, Some(error), Some(minimum_separation))
.iter()
.map(|intersection_t| {
let point = self.0.evaluate(SubpathTValue::GlobalParametric(*intersection_t));
.map(|(segment_index, intersection_t)| {
let point = self.0.evaluate(SubpathTValue::Parametric {
segment_index: *segment_index,
t: *intersection_t,
});
draw_circle(point, 4., RED, 1.5, WHITE)
})
.fold(String::new(), |acc, item| format!("{acc}{item}"));
@@ -208,7 +211,7 @@ impl WasmSubpath {
wrap_svg_tag(format!("{subpath_svg}{line_svg}{intersections_svg}"))
}
pub fn intersect_quadratic_segment(&self, js_points: JsValue) -> String {
pub fn intersect_quadratic_segment(&self, js_points: JsValue, error: f64, minimum_separation: f64) -> String {
let points: [DVec2; 3] = serde_wasm_bindgen::from_value(js_points).unwrap();
let line = Bezier::from_quadratic_dvec2(points[0], points[1], points[2]);
@@ -226,10 +229,13 @@ impl WasmSubpath {
let intersections_svg = self
.0
.intersections(&line, None, None)
.intersections(&line, Some(error), Some(minimum_separation))
.iter()
.map(|intersection_t| {
let point = self.0.evaluate(SubpathTValue::GlobalParametric(*intersection_t));
.map(|(segment_index, intersection_t)| {
let point = self.0.evaluate(SubpathTValue::Parametric {
segment_index: *segment_index,
t: *intersection_t,
});
draw_circle(point, 4., RED, 1.5, WHITE)
})
.fold(String::new(), |acc, item| format!("{acc}{item}"));
@@ -237,7 +243,7 @@ impl WasmSubpath {
wrap_svg_tag(format!("{subpath_svg}{line_svg}{intersections_svg}"))
}
pub fn intersect_cubic_segment(&self, js_points: JsValue) -> String {
pub fn intersect_cubic_segment(&self, js_points: JsValue, error: f64, minimum_separation: f64) -> String {
let points: [DVec2; 4] = serde_wasm_bindgen::from_value(js_points).unwrap();
let line = Bezier::from_cubic_dvec2(points[0], points[1], points[2], points[3]);
@@ -255,10 +261,13 @@ impl WasmSubpath {
let intersections_svg = self
.0
.intersections(&line, None, None)
.intersections(&line, Some(error), Some(minimum_separation))
.iter()
.map(|intersection_t| {
let point = self.0.evaluate(SubpathTValue::GlobalParametric(*intersection_t));
.map(|(segment_index, intersection_t)| {
let point = self.0.evaluate(SubpathTValue::Parametric {
segment_index: *segment_index,
t: *intersection_t,
});
draw_circle(point, 4., RED, 1.5, WHITE)
})
.fold(String::new(), |acc, item| format!("{acc}{item}"));
@@ -266,6 +275,24 @@ impl WasmSubpath {
wrap_svg_tag(format!("{subpath_svg}{line_svg}{intersections_svg}"))
}
pub fn self_intersections(&self, error: f64, minimum_separation: f64) -> String {
let subpath_svg = self.to_default_svg();
let self_intersections_svg = self
.0
.self_intersections(Some(error), Some(minimum_separation))
.iter()
.map(|(segment_index, intersection_t)| {
let point = self.0.evaluate(SubpathTValue::Parametric {
segment_index: *segment_index,
t: *intersection_t,
});
draw_circle(point, 4., RED, 1.5, WHITE)
})
.fold(String::new(), |acc, item| format!("{acc}{item}"));
wrap_svg_tag(format!("{subpath_svg}{self_intersections_svg}"))
}
pub fn split(&self, t: f64, t_variant: String) -> String {
let t = parse_t_variant(&t_variant, t);
let (main_subpath, optional_subpath) = self.0.split(t);