veloren_common/util/
lines.rs1use vek::{LineSegment3, Vec3};
2
3pub fn closest_points_3d(n: LineSegment3<f32>, m: LineSegment3<f32>) -> (Vec3<f32>, Vec3<f32>) {
5 let p1 = n.start;
6 let p2 = n.end;
7 let p3 = m.start;
8 let p4 = m.end;
9
10 let d1 = p2 - p1;
11 let d2 = p4 - p3;
12 let d21 = p3 - p1;
13
14 let v22 = d2.dot(d2);
15 let v11 = d1.dot(d1);
16 let v21 = d2.dot(d1);
17 let v21_1 = d21.dot(d1);
18 let v21_2 = d21.dot(d2);
19
20 let denom = v21 * v21 - v22 * v11;
21
22 let (s, t) = if denom == 0.0 {
23 let s = 0.0;
24 let t = (v11 * s - v21_1) / v21;
25 (s, t)
26 } else {
27 let s = (v21_2 * v21 - v22 * v21_1) / denom;
28 let t = (-v21_1 * v21 + v11 * v21_2) / denom;
29 (s, t)
30 };
31
32 let (s, t) = (s.clamp(0.0, 1.0), t.clamp(0.0, 1.0));
33
34 let p_a = p1 + s * d1;
35 let p_b = p3 + t * d2;
36
37 (p_a, p_b)
38}