parry3d/query/closest_points/
closest_points_line_line.rs1use crate::math::{Real, Vector};
2
3#[inline]
8pub fn closest_points_line_line_parameters(
9 orig1: Vector,
10 dir1: Vector,
11 orig2: Vector,
12 dir2: Vector,
13) -> (Real, Real) {
14 let res = closest_points_line_line_parameters_eps(
15 orig1,
16 dir1,
17 orig2,
18 dir2,
19 crate::math::DEFAULT_EPSILON,
20 );
21 (res.0, res.1)
22}
23
24#[inline]
31pub fn closest_points_line_line_parameters_eps(
32 orig1: Vector,
33 dir1: Vector,
34 orig2: Vector,
35 dir2: Vector,
36 eps: Real,
37) -> (Real, Real, bool) {
38 let r = orig1 - orig2;
40
41 let a = dir1.length_squared();
42 let e = dir2.length_squared();
43 let f = dir2.dot(r);
44
45 if a <= eps && e <= eps {
46 (0.0, 0.0, false)
47 } else if a <= eps {
48 (0.0, f / e, false)
49 } else {
50 let c = dir1.dot(r);
51 if e <= eps {
52 (-c / a, 0.0, false)
53 } else {
54 let b = dir1.dot(dir2);
55 let ae = a * e;
56 let bb = b * b;
57 let denom = ae - bb;
58
59 let parallel = denom <= eps || ulps_eq!(ae, bb);
61
62 let s = if !parallel {
63 (b * f - c * e) / denom
64 } else {
65 0.0
66 };
67
68 (s, (b * s + f) / e, parallel)
69 }
70 }
71}
72
73#[inline]
76pub fn closest_points_line_line(
77 orig1: Vector,
78 dir1: Vector,
79 orig2: Vector,
80 dir2: Vector,
81) -> (Vector, Vector) {
82 let (s, t) = closest_points_line_line_parameters(orig1, dir1, orig2, dir2);
83 (orig1 + dir1 * s, orig2 + dir2 * t)
84}