mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 21:37:59 +00:00
parent
7a56af01ef
commit
f7d83d2632
5 changed files with 95 additions and 16 deletions
|
@ -380,17 +380,24 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
|||
///
|
||||
/// Alternatively, this can be interpreted as limiting the angle that the miter can form.
|
||||
/// When the limit is exceeded, no manipulator group will be returned.
|
||||
/// This value should be at least 1. If not, the default of 4 will be used.
|
||||
/// This value should be greater than 0. If not, the default of 4 will be used.
|
||||
pub(crate) fn miter_line_join(&self, other: &Subpath<PointId>, miter_limit: Option<f64>) -> Option<ManipulatorGroup<PointId>> {
|
||||
let miter_limit = match miter_limit {
|
||||
Some(miter_limit) if miter_limit >= 1. => miter_limit,
|
||||
Some(miter_limit) if miter_limit > f64::EPSILON => miter_limit,
|
||||
_ => 4.,
|
||||
};
|
||||
let in_segment = self.get_segment(self.len_segments() - 1).unwrap();
|
||||
let out_segment = other.get_segment(0).unwrap();
|
||||
// TODO: Besides returning None using the `?` operator, is there a more appropriate way to handle a `None` result from `get_segment`?
|
||||
let in_segment = self.get_segment(self.len_segments() - 1)?;
|
||||
let out_segment = other.get_segment(0)?;
|
||||
|
||||
let in_tangent = in_segment.tangent(TValue::Parametric(1.));
|
||||
let out_tangent = out_segment.tangent(TValue::Parametric(0.));
|
||||
|
||||
if in_tangent == DVec2::ZERO || out_tangent == DVec2::ZERO {
|
||||
// Avoid panic from normalizing zero vectors
|
||||
// TODO: Besides returning None, is there a more appropriate way to handle this?
|
||||
return None;
|
||||
}
|
||||
let normalized_in_tangent = in_tangent.normalize();
|
||||
let normalized_out_tangent = out_tangent.normalize();
|
||||
|
||||
|
@ -400,11 +407,16 @@ impl<PointId: crate::Identifier> Subpath<PointId> {
|
|||
|
||||
let start_to_intersection = intersection - in_segment.end();
|
||||
let intersection_to_end = out_segment.start() - intersection;
|
||||
if start_to_intersection == DVec2::ZERO || intersection_to_end == DVec2::ZERO {
|
||||
// Avoid panic from normalizing zero vectors
|
||||
// TODO: Besides returning None, is there a more appropriate way to handle this?
|
||||
return None;
|
||||
}
|
||||
|
||||
// Draw the miter join if the intersection occurs in the correct direction with respect to the path
|
||||
if start_to_intersection.normalize().abs_diff_eq(in_tangent, MAX_ABSOLUTE_DIFFERENCE)
|
||||
&& intersection_to_end.normalize().abs_diff_eq(out_tangent, MAX_ABSOLUTE_DIFFERENCE)
|
||||
&& miter_limit >= 1. / (start_to_intersection.angle_to(-intersection_to_end).abs() / 2.).sin()
|
||||
&& miter_limit > f64::EPSILON / (start_to_intersection.angle_to(-intersection_to_end).abs() / 2.).sin()
|
||||
{
|
||||
return Some(ManipulatorGroup {
|
||||
anchor: intersection,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue