Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find tangents from point to cubic Bézier #288

Merged
merged 3 commits into from
Aug 22, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/cubicbez.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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.
Copy link

@Keavon Keavon Jun 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On my initial few read-throughs of this sentence I had a hard time groking it. I can also take a shot at wording it, which might also be flawed, but maybe we can meet in the middle with something that's clearer to unbiased readers:

Find points on the curve where each one's tangent line passes through the given point p in space.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it a little shorter (it should be one line), but agree this is clearer. I think in my mind I was thinking about the line from the point to the curve, but thinking about it the other way is simpler because it's more apparent that you're getting both the tangent and the incidence.

///
/// 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<f64, 4> {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would tangents_though_point be a clearer name?

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.
Expand Down