Files
Graphite/bezier-rs/lib/src/structs.rs
T
b2ddeea954 Implement arcs for Bezier math library (#731)
* added arcs impl

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

* fixed arc drawing,  todo - fix linear check

Co-authored-by: Hannah Li <hannahli2010@gmail.com>

* fixed linear bug + added comments and tests

Co-authored-by: Hannah Li <hannahli2010@gmail.com>

* added max iteration guard + made params optional  + added impl todo

* Add functionality to get arcs between extrema

* Add ArcsOptions to manage optional parameters of the arcs function

* added slider to toggle between arcs impl

Co-authored-by: Rob Nadal <RobNadal@users.noreply.github.com>

* Remove unused types

* address some comments

* added rustdoc for CircularArc struct

* Extract duplicate code into helper, remove loop labels, use window function

* Make JsValue handling consistent in WasmBezier and add comments for the underlying type

* Add enum for MaximizeArcs Auto/On/Off functionality

* Change Auto to Automatic

* fix errors from resolving merge conflict

* fixed error from resolving merge conflicts

* fixed formatting

* address comments

* Small fix

* Add some missing comments

* address comments

* rename variable

* Use unit to show maximize_arcs values

* Change i32 to usize and other minor adjustments

* Change computation for middle t values

* Remove tsconfig

* Fix more usize number handling

Co-authored-by: Hannah Li <hannahli2010@gmail.com>
Co-authored-by: Rob Nadal <RobNadal@users.noreply.github.com>
Co-authored-by: Keavon Chambers <keavon@keavon.com>
2022-08-05 22:34:39 -07:00

96 lines
3.6 KiB
Rust

use glam::DVec2;
use std::fmt::{Debug, Formatter, Result};
/// Struct to represent optional parameters that can be passed to the `project` function.
#[derive(Copy, Clone)]
pub struct ProjectionOptions {
/// Size of the lookup table for the initial passthrough. The default value is `20`.
pub lut_size: usize,
/// Difference used between floating point numbers to be considered as equal. The default value is `0.0001`
pub convergence_epsilon: f64,
/// Controls the number of iterations needed to consider that minimum distance to have converged. The default value is `3`.
pub convergence_limit: usize,
/// Controls the maximum total number of iterations to be used. The default value is `10`.
pub iteration_limit: usize,
}
impl Default for ProjectionOptions {
fn default() -> Self {
ProjectionOptions {
lut_size: 20,
convergence_epsilon: 1e-4,
convergence_limit: 3,
iteration_limit: 10,
}
}
}
/// Struct used to represent the different strategies for generating arc approximations.
#[derive(Copy, Clone)]
pub enum ArcStrategy {
/// Start with the greedy strategy of maximizing arc approximations and automatically switch to the divide-and-conquer when the greedy approximations no longer fall within the error bound.
Automatic,
/// Use the greedy strategy to maximize approximated arcs, despite potentially erroneous arcs.
FavorLargerArcs,
/// Use the divide-and-conquer strategy that prioritizes correctness over maximal arcs.
FavorCorrectness,
}
/// Struct to represent optional parameters that can be passed to the `arcs` function.
#[derive(Copy, Clone)]
pub struct ArcsOptions {
/// Determines how the approximated arcs are computed.
/// When maximizing the arcs, the algorithm may return incorrect arcs when the curve contains any small loops or segments that look like a very thin "U".
/// The enum options behave as follows:
/// - `Automatic`: Maximize arcs until an erroneous approximation is found. Compute the arcs of the rest of the curve by first splitting on extremas to ensure no more erroneous cases are encountered.
/// - `FavorLargerArcs`: Maximize arcs using the original algorithm from the [Approximating a Bezier curve with circular arcs](https://pomax.github.io/bezierinfo/#arcapproximation) section of Pomax's bezier curve primer. Erroneous arcs are possible.
/// - `FavorCorrectness`: Prioritize correctness by first spliting the curve by its extremas and determine the arc approximation of each segment instead.
///
/// The default value is `Automatic`.
pub strategy: ArcStrategy,
/// The error used for approximating the arc's fit. The default is `0.5`.
pub error: f64,
/// The maximum number of segment iterations used as attempts for arc approximations. The default is `100`.
pub max_iterations: usize,
}
impl Default for ArcsOptions {
fn default() -> Self {
ArcsOptions {
strategy: ArcStrategy::Automatic,
error: 0.5,
max_iterations: 100,
}
}
}
/// Struct to represent the circular arc approximation used in the `arcs` bezier function.
#[derive(Copy, Clone, PartialEq)]
pub struct CircleArc {
/// The center point of the circle.
pub center: DVec2,
/// The radius of the circle.
pub radius: f64,
/// The start angle of the circle sector in rad.
pub start_angle: f64,
/// The end angle of the circle sector in rad.
pub end_angle: f64,
}
impl Debug for CircleArc {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "Center: {}, radius: {}, start to end angles: {} to {}", self.center, self.radius, self.start_angle, self.end_angle)
}
}
impl Default for CircleArc {
fn default() -> Self {
CircleArc {
center: DVec2::ZERO,
radius: 0.,
start_angle: 0.,
end_angle: 0.,
}
}
}