mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-04 00:08:11 +08:00
Bezier-rs: Add joins and caps to offsets and outlines (#1083)
* Intial work * Improve miter and add round join * Get arcs to go opposite direction * Add cap and other refactors * Rename joint to join, fix some bugs * Fix single point issue * Clean up * Fix iframe sizes and update UI * Address comments and handle single point outline * Rename variables, fix branches in outline * Address comments
This commit is contained in:
committed by
Keavon Chambers
parent
7e124c8035
commit
c0576ab4e0
@@ -1,4 +1,5 @@
|
||||
use crate::consts::{MAX_ABSOLUTE_DIFFERENCE, MIN_SEPARATION_VALUE, STRICT_MAX_ABSOLUTE_DIFFERENCE};
|
||||
use crate::ManipulatorGroup;
|
||||
|
||||
use glam::{BVec2, DMat2, DVec2};
|
||||
use std::f64::consts::PI;
|
||||
@@ -29,12 +30,23 @@ pub enum SubpathTValue {
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Joint {
|
||||
Miter,
|
||||
/// Enum to represent the join type between subpaths.
|
||||
/// As defined in SVG: https://www.w3.org/TR/SVG2/painting.html#LineJoin.
|
||||
pub enum Join {
|
||||
Bevel,
|
||||
Miter,
|
||||
Round,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
/// Enum to represent the cap type at the ends of an outline
|
||||
/// As defined in SVG: https://www.w3.org/TR/SVG2/painting.html#LineCaps.
|
||||
pub enum Cap {
|
||||
Butt,
|
||||
Round,
|
||||
Square,
|
||||
}
|
||||
|
||||
/// Helper to perform the computation of a and c, where b is the provided point on the curve.
|
||||
/// Given the correct power of `t` and `(1-t)`, the computation is the same for quadratic and cubic cases.
|
||||
/// Relevant derivation and the definitions of a, b, and c can be found in [the projection identity section](https://pomax.github.io/bezierinfo/#abc) of Pomax's bezier curve primer.
|
||||
@@ -266,6 +278,31 @@ pub fn scale_point_from_origin(point: DVec2, origin: DVec2, should_flip_directio
|
||||
scale_point_from_direction_vector(point, (origin - point).normalize(), should_flip_direction, distance)
|
||||
}
|
||||
|
||||
/// Computes the necessary details to form a circular join from `left` to `right`, along a circle around `center`.
|
||||
/// By default, the angle is assumed to be 180 degrees.
|
||||
pub fn compute_circular_subpath_details<ManipulatorGroupId: crate::Identifier>(
|
||||
left: DVec2,
|
||||
arc_point: DVec2,
|
||||
right: DVec2,
|
||||
center: DVec2,
|
||||
angle: Option<f64>,
|
||||
) -> (DVec2, ManipulatorGroup<ManipulatorGroupId>, DVec2) {
|
||||
let center_to_arc_point = arc_point - center;
|
||||
|
||||
// Based on https://pomax.github.io/bezierinfo/#circles_cubic
|
||||
let handle_offset_factor = if let Some(angle) = angle { 4. / 3. * (angle / 4.).tan() } else { 0.551784777779014 };
|
||||
|
||||
(
|
||||
left - (left - center).perp() * handle_offset_factor,
|
||||
ManipulatorGroup::new(
|
||||
arc_point,
|
||||
Some(arc_point + center_to_arc_point.perp() * handle_offset_factor),
|
||||
Some(arc_point - center_to_arc_point.perp() * handle_offset_factor),
|
||||
),
|
||||
right + (right - center).perp() * handle_offset_factor,
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user