From ed63f433591c24cbc653aede495d5927e28db0f1 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Thu, 1 Jun 2023 17:31:42 -0700 Subject: [PATCH 1/2] =?UTF-8?q?Find=20tangents=20from=20point=20to=20cubic?= =?UTF-8?q?=20B=C3=A9zier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cubicbez.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/cubicbez.rs b/src/cubicbez.rs index 68be82e1..39f38c76 100644 --- a/src/cubicbez.rs +++ b/src/cubicbez.rs @@ -12,7 +12,7 @@ use crate::{Line, QuadSpline, Vec2}; use arrayvec::ArrayVec; use crate::common::{ - solve_quadratic, GAUSS_LEGENDRE_COEFFS_16_HALF, GAUSS_LEGENDRE_COEFFS_24_HALF, + solve_quadratic, solve_quartic, GAUSS_LEGENDRE_COEFFS_16_HALF, GAUSS_LEGENDRE_COEFFS_24_HALF, GAUSS_LEGENDRE_COEFFS_8, GAUSS_LEGENDRE_COEFFS_8_HALF, }; use crate::{ @@ -348,6 +348,26 @@ impl CubicBez { .filter(|t| *t >= 0.0 && *t <= 1.0) .collect() } + + /// Find lines from the point to the curve tangent to the curve. + /// + /// Result is array of t values such that the line from the given point + /// to the curve evaluated at that value is tangent to the curve. + pub fn point_tangents(&self, p: Point) -> ArrayVec { + let (a, b, c, d_orig) = self.parameters(); + let d = d_orig - p.to_vec2(); + // coefficients of x(t) \cross x'(t) + let c4 = b.cross(a); + let c3 = 2.0 * c.cross(a); + let c2 = c.cross(b) + 3.0 * d.cross(a); + let c1 = 2.0 * d.cross(b); + let c0 = d.cross(c); + solve_quartic(c0, c1, c2, c3, c4) + .iter() + .copied() + .filter(|t| *t >= 0.0 && *t <= 1.0) + .collect() + } } /// An iterator for cubic beziers. From 5cdb803b8d5f867f7b414c6700bfa6d7ee358110 Mon Sep 17 00:00:00 2001 From: Raph Levien Date: Fri, 2 Jun 2023 07:06:58 -0700 Subject: [PATCH 2/2] Naming and docstring changes. --- src/cubicbez.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cubicbez.rs b/src/cubicbez.rs index 39f38c76..04a43c1a 100644 --- a/src/cubicbez.rs +++ b/src/cubicbez.rs @@ -349,11 +349,12 @@ impl CubicBez { .collect() } - /// Find lines from the point to the curve tangent to the curve. + /// Find points on the curve where the tangent line passes through the + /// given point. /// - /// Result is array of t values such that the line from the given point - /// to the curve evaluated at that value is tangent to the curve. - pub fn point_tangents(&self, p: Point) -> ArrayVec { + /// Result is array of t values such that the tangent line from the curve + /// evaluated at that point goes through the argument point. + pub fn tangents_to_point(&self, p: Point) -> ArrayVec { let (a, b, c, d_orig) = self.parameters(); let d = d_orig - p.to_vec2(); // coefficients of x(t) \cross x'(t)