mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-10 03:30:56 +08:00
Bezier-rs: Add Euclidean parameterization to Bezier::evaluate (#828)
* Add enum to evaluate for differenciating compute type * Add euclidean parameterization and update styling in the UI Co-authored-by: Rob Nadal <robnadal44@gmail.com> * Update usage of evaluate in graphite * Add description * Code review changes * Update tests * Improve ComputeType ergonomics * Large code review/cleanup pass Co-authored-by: Rob Nadal <robnadal44@gmail.com> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Rob Nadal
Keavon Chambers
parent
a220bfa759
commit
01a9724389
@@ -1,5 +1,5 @@
|
||||
use crate::svg_drawing::*;
|
||||
use bezier_rs::{ArcStrategy, ArcsOptions, Bezier, ProjectionOptions};
|
||||
use bezier_rs::{ArcStrategy, ArcsOptions, Bezier, ComputeType, ProjectionOptions};
|
||||
use glam::DVec2;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen::prelude::*;
|
||||
@@ -132,10 +132,14 @@ impl WasmBezier {
|
||||
wrap_svg_tag(format!("{bezier}{}", draw_text(format!("Length: {:.2}", self.0.length(None)), TEXT_OFFSET_X, TEXT_OFFSET_Y, BLACK)))
|
||||
}
|
||||
|
||||
pub fn evaluate(&self, t: f64) -> String {
|
||||
pub fn evaluate(&self, t: f64, compute_type: String) -> String {
|
||||
let bezier = self.get_bezier_path();
|
||||
let point = &self.0.evaluate(t);
|
||||
let content = format!("{bezier}{}", draw_circle(*point, 4., RED, 1.5, WHITE));
|
||||
let point = match compute_type.as_str() {
|
||||
"Euclidean" => self.0.evaluate(ComputeType::Euclidean(t)),
|
||||
"Parametric" => self.0.evaluate(ComputeType::Parametric(t)),
|
||||
_ => panic!("Unexpected ComputeType string: '{}'", compute_type),
|
||||
};
|
||||
let content = format!("{bezier}{}", draw_circle(point, 4., RED, 1.5, WHITE));
|
||||
wrap_svg_tag(content)
|
||||
}
|
||||
|
||||
@@ -173,7 +177,7 @@ impl WasmBezier {
|
||||
let bezier = self.get_bezier_path();
|
||||
|
||||
let tangent_point = self.0.tangent(t);
|
||||
let intersection_point = self.0.evaluate(t);
|
||||
let intersection_point = self.0.evaluate(ComputeType::Parametric(t));
|
||||
let tangent_end = intersection_point + tangent_point * SCALE_UNIT_VECTOR_FACTOR;
|
||||
|
||||
let content = format!(
|
||||
@@ -189,7 +193,7 @@ impl WasmBezier {
|
||||
let bezier = self.get_bezier_path();
|
||||
|
||||
let normal_point = self.0.normal(t);
|
||||
let intersection_point = self.0.evaluate(t);
|
||||
let intersection_point = self.0.evaluate(ComputeType::Parametric(t));
|
||||
let normal_end = intersection_point + normal_point * SCALE_UNIT_VECTOR_FACTOR;
|
||||
|
||||
let content = format!(
|
||||
@@ -205,7 +209,7 @@ impl WasmBezier {
|
||||
let bezier = self.get_bezier_path();
|
||||
let radius = 1. / self.0.curvature(t);
|
||||
let normal_point = self.0.normal(t);
|
||||
let intersection_point = self.0.evaluate(t);
|
||||
let intersection_point = self.0.evaluate(ComputeType::Parametric(t));
|
||||
|
||||
let curvature_center = intersection_point + normal_point * radius;
|
||||
|
||||
@@ -269,7 +273,7 @@ impl WasmBezier {
|
||||
|
||||
pub fn project(&self, x: f64, y: f64) -> String {
|
||||
let projected_t_value = self.0.project(DVec2::new(x, y), ProjectionOptions::default());
|
||||
let projected_point = self.0.evaluate(projected_t_value);
|
||||
let projected_point = self.0.evaluate(ComputeType::Parametric(projected_t_value));
|
||||
|
||||
let bezier = self.get_bezier_path();
|
||||
let content = format!("{bezier}{}", draw_line(projected_point.x, projected_point.y, x, y, RED, 1.),);
|
||||
@@ -285,7 +289,7 @@ impl WasmBezier {
|
||||
.zip([RED, GREEN])
|
||||
.flat_map(|(t_value_list, color)| {
|
||||
t_value_list.iter().map(|&t_value| {
|
||||
let point = self.0.evaluate(t_value);
|
||||
let point = self.0.evaluate(ComputeType::Parametric(t_value));
|
||||
draw_circle(point, 3., color, 1.5, WHITE)
|
||||
})
|
||||
})
|
||||
@@ -320,7 +324,7 @@ impl WasmBezier {
|
||||
let circles: String = inflections
|
||||
.iter()
|
||||
.map(|&t_value| {
|
||||
let point = self.0.evaluate(t_value);
|
||||
let point = self.0.evaluate(ComputeType::Parametric(t_value));
|
||||
draw_circle(point, 3., RED, 1.5, WHITE)
|
||||
})
|
||||
.fold("".to_string(), |acc, circle| acc + &circle);
|
||||
@@ -413,7 +417,7 @@ impl WasmBezier {
|
||||
.intersect(&line, None)
|
||||
.iter()
|
||||
.map(|intersection_t| {
|
||||
let point = &self.0.evaluate(*intersection_t);
|
||||
let point = &self.0.evaluate(ComputeType::Parametric(*intersection_t));
|
||||
draw_circle(*point, 4., RED, 1.5, WHITE)
|
||||
})
|
||||
.fold(String::new(), |acc, item| format!("{acc}{item}"));
|
||||
@@ -433,7 +437,7 @@ impl WasmBezier {
|
||||
.intersect(&quadratic, Some(error))
|
||||
.iter()
|
||||
.map(|intersection_t| {
|
||||
let point = &self.0.evaluate(*intersection_t);
|
||||
let point = &self.0.evaluate(ComputeType::Parametric(*intersection_t));
|
||||
draw_circle(*point, 4., RED, 1.5, WHITE)
|
||||
})
|
||||
.fold(String::new(), |acc, item| format!("{acc}{item}"));
|
||||
@@ -453,7 +457,7 @@ impl WasmBezier {
|
||||
.intersect(&cubic, Some(error))
|
||||
.iter()
|
||||
.map(|intersection_t| {
|
||||
let point = &self.0.evaluate(*intersection_t);
|
||||
let point = &self.0.evaluate(ComputeType::Parametric(*intersection_t));
|
||||
draw_circle(*point, 4., RED, 1.5, WHITE)
|
||||
})
|
||||
.fold(String::new(), |acc, item| format!("{acc}{item}"));
|
||||
@@ -469,7 +473,7 @@ impl WasmBezier {
|
||||
.self_intersections(Some(error))
|
||||
.iter()
|
||||
.map(|intersection_t| {
|
||||
let point = &self.0.evaluate(intersection_t[0]);
|
||||
let point = &self.0.evaluate(ComputeType::Parametric(intersection_t[0]));
|
||||
draw_circle(*point, 4., RED, 1.5, WHITE)
|
||||
})
|
||||
.fold(bezier_curve_svg, |acc, item| format!("{acc}{item}"));
|
||||
|
||||
Reference in New Issue
Block a user