ncollide3d/query/closest_points/
closest_points_line_line.rs1use crate::math::{Point, Vector};
2use na::{self, RealField};
3
4#[inline]
9pub fn closest_points_line_line_parameters<N: RealField + Copy>(
10 orig1: &Point<N>,
11 dir1: &Vector<N>,
12 orig2: &Point<N>,
13 dir2: &Vector<N>,
14) -> (N, N) {
15 let res =
16 closest_points_line_line_parameters_eps(orig1, dir1, orig2, dir2, N::default_epsilon());
17 (res.0, res.1)
18}
19
20#[inline]
27pub fn closest_points_line_line_parameters_eps<N: RealField + Copy>(
28 orig1: &Point<N>,
29 dir1: &Vector<N>,
30 orig2: &Point<N>,
31 dir2: &Vector<N>,
32 eps: N,
33) -> (N, N, bool) {
34 let r = *orig1 - *orig2;
36
37 let a = dir1.norm_squared();
38 let e = dir2.norm_squared();
39 let f = dir2.dot(&r);
40
41 let _0: N = na::zero();
42 let _1: N = na::one();
43
44 if a <= eps && e <= eps {
45 (_0, _0, false)
46 } else if a <= eps {
47 (_0, f / e, false)
48 } else {
49 let c = dir1.dot(&r);
50 if e <= eps {
51 (-c / a, _0, false)
52 } else {
53 let b = dir1.dot(dir2);
54 let ae = a * e;
55 let bb = b * b;
56 let denom = ae - bb;
57
58 let parallel = denom <= eps || ulps_eq!(ae, bb);
60
61 let s = if !parallel {
62 (b * f - c * e) / denom
63 } else {
64 _0
65 };
66
67 (s, (b * s + f) / e, parallel)
68 }
69 }
70}
71
72#[inline]
75pub fn closest_points_line_line<N: RealField + Copy>(
76 orig1: &Point<N>,
77 dir1: &Vector<N>,
78 orig2: &Point<N>,
79 dir2: &Vector<N>,
80) -> (Point<N>, Point<N>) {
81 let (s, t) = closest_points_line_line_parameters(orig1, dir1, orig2, dir2);
82 (*orig1 + *dir1 * s, *orig2 + *dir2 * t)
83}