Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save tesselode/49bf413af2ff0a6f70148acb33a5d28b to your computer and use it in GitHub Desktop.
Save tesselode/49bf413af2ff0a6f70148acb33a5d28b to your computer and use it in GitHub Desktop.
Returns the entrance and exit intersections of a line segment with a circle
// based on https://stackoverflow.com/a/1084899
// Vec2 is from the vek crate
type Entrance = Vec2<f32>;
type Exit = Vec2<f32>;
fn line_segment_and_circle_intersections(
line_segment_start: Vec2<f32>,
line_segment_end: Vec2<f32>,
circle_center: Vec2<f32>,
circle_radius: f32,
) -> (Option<Entrance>, Option<Exit>) {
let d = line_segment_end - line_segment_start;
let f = line_segment_start - circle_center;
let a = d.dot(d);
let b = 2.0 * f.dot(d);
let c = f.dot(f) - circle_radius * circle_radius;
let mut discriminant = b * b - 4.0 * a * c;
if discriminant < 0.0 {
return (None, None);
}
discriminant = discriminant.sqrt();
let t1 = (-b - discriminant) / (2.0 * a);
let t2 = (-b + discriminant) / (2.0 * a);
let intersection1 = if t1 >= 0.0 && t1 <= 1.0 {
Some(line_segment_start + (line_segment_end - line_segment_start) * t1)
} else {
None
};
let intersection2 = if t2 >= 0.0 && t2 <= 1.0 {
Some(line_segment_start + (line_segment_end - line_segment_start) * t2)
} else {
None
};
(intersection1, intersection2)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment