pub fn closest_approach(&self, other: &Self) -> f64 {
let a = self.a - other.a;
let b = self.b - other.b;
let c = self.c - other.c;
// first check for a place where the distance is 0
// within margin of error
let qf = |e: &dyn Fn(V3) -> f64| {
vec![
(-e(b) - (e(b) * e(b) - 4. * e(a) * e(c)).sqrt()) / 2. * e(a),
(-e(b) + (e(b) * e(b) - 4. * e(a) * e(c)).sqrt()) / 2. * e(a),
]
};
let mut origins: Vec<f64> = qf(&|v: V3| v.x);
for e in [
&(|v: V3| v.y) as &dyn Fn(V3) -> f64,
&(|v: V3| v.z) as &dyn Fn(V3) -> f64,
]
.iter()
{
let other = qf(e);
origins.drain_filter(|o1| other.iter().all(|o2| (*o1 - o2).abs() > 1e-50));
}
if origins.len() > 0 {
origins[0]
} else {
// I'm so sorry! (converted from Wolfram Alpha output)
-((a.x * b.x + a.y * b.y + a.z * b.z)
/ (2. * (f64::powi(a.x, 2) + f64::powi(a.y, 2) + f64::powi(a.z, 2))))
+ f64::powf(
-(108. * b.y * c.y * f64::powi(a.x, 4)) - 108. * b.z * c.z * f64::powi(a.x, 4)
+ 54. * b.x * f64::powi(b.y, 2) * f64::powi(a.x, 3)
+ 54. * b.x * f64::powi(b.z, 2) * f64::powi(a.x, 3)
+ 108. * c.x * a.y * b.y * f64::powi(a.x, 3)
+ 108. * b.x * a.y * c.y * f64::powi(a.x, 3)
+ 108. * c.x * a.z * b.z * f64::powi(a.x, 3)
+ 108. * b.x * a.z * c.z * f64::powi(a.x, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.x, 2)
+ 54. * a.z * f64::powi(b.z, 3) * f64::powi(a.x, 2)
- 108. * b.x * c.x * f64::powi(a.y, 2) * f64::powi(a.x, 2)
- 108. * b.x * c.x * f64::powi(a.z, 2) * f64::powi(a.x, 2)
- 216. * b.y * c.y * f64::powi(a.z, 2) * f64::powi(a.x, 2)
+ 54. * a.y * b.y * f64::powi(b.z, 2) * f64::powi(a.x, 2)
- 108. * f64::powi(b.x, 2) * a.y * b.y * f64::powi(a.x, 2)
- 108. * f64::powi(a.y, 2) * b.y * c.y * f64::powi(a.x, 2)
- 108. * f64::powi(b.x, 2) * a.z * b.z * f64::powi(a.x, 2)
+ 54. * f64::powi(b.y, 2) * a.z * b.z * f64::powi(a.x, 2)
+ 108. * a.y * c.y * a.z * b.z * f64::powi(a.x, 2)
+ 108. * a.y * b.y * a.z * c.z * f64::powi(a.x, 2)
- 216. * f64::powi(a.y, 2) * b.z * c.z * f64::powi(a.x, 2)
- 108. * f64::powi(a.z, 2) * b.z * c.z * f64::powi(a.x, 2)
+ 54. * f64::powi(b.x, 3) * f64::powi(a.y, 2) * a.x
- 108. * b.x * f64::powi(a.y, 2) * f64::powi(b.y, 2) * a.x
+ 54. * f64::powi(b.x, 3) * f64::powi(a.z, 2) * a.x
+ 54. * b.x * f64::powi(b.y, 2) * f64::powi(a.z, 2) * a.x
+ 108. * c.x * a.y * b.y * f64::powi(a.z, 2) * a.x
+ 108. * b.x * a.y * c.y * f64::powi(a.z, 2) * a.x
+ 54. * b.x * f64::powi(a.y, 2) * f64::powi(b.z, 2) * a.x
- 108. * b.x * f64::powi(a.z, 2) * f64::powi(b.z, 2) * a.x
+ 108. * c.x * f64::powi(a.y, 3) * b.y * a.x
+ 108. * b.x * f64::powi(a.y, 3) * c.y * a.x
+ 108. * c.x * f64::powi(a.z, 3) * b.z * a.x
+ 108. * c.x * f64::powi(a.y, 2) * a.z * b.z * a.x
- 324. * b.x * a.y * b.y * a.z * b.z * a.x
+ 108. * b.x * f64::powi(a.z, 3) * c.z * a.x
+ 108. * b.x * f64::powi(a.y, 2) * a.z * c.z * a.x
- 108. * b.x * c.x * f64::powi(a.y, 4)
- 108. * b.x * c.x * f64::powi(a.z, 4)
- 108. * b.y * c.y * f64::powi(a.z, 4)
+ 54. * f64::powi(a.y, 2) * a.z * f64::powi(b.z, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.z, 2)
- 216. * b.x * c.x * f64::powi(a.y, 2) * f64::powi(a.z, 2)
+ 54. * f64::powi(b.x, 2) * a.y * b.y * f64::powi(a.z, 2)
- 108. * f64::powi(a.y, 2) * b.y * c.y * f64::powi(a.z, 2)
- 108. * a.y * b.y * f64::powi(a.z, 2) * f64::powi(b.z, 2)
+ 54. * f64::powi(a.y, 3) * b.y * f64::powi(b.z, 2)
+ 54. * f64::powi(b.x, 2) * f64::powi(a.y, 3) * b.y
+ 54. * f64::powi(b.x, 2) * f64::powi(a.z, 3) * b.z
+ 54. * f64::powi(b.y, 2) * f64::powi(a.z, 3) * b.z
+ 108. * a.y * c.y * f64::powi(a.z, 3) * b.z
+ 54. * f64::powi(b.x, 2) * f64::powi(a.y, 2) * a.z * b.z
- 108. * f64::powi(a.y, 2) * f64::powi(b.y, 2) * a.z * b.z
+ 108. * f64::powi(a.y, 3) * c.y * a.z * b.z
+ 108. * a.y * b.y * f64::powi(a.z, 3) * c.z
+ 108. * f64::powi(a.y, 3) * b.y * a.z * c.z
- 108. * f64::powi(a.y, 4) * b.z * c.z
- 108. * f64::powi(a.y, 2) * f64::powi(a.z, 2) * b.z * c.z
+ f64::sqrt(
4. * f64::powi(
6. * (f64::powi(a.x, 2) + f64::powi(a.y, 2) + f64::powi(a.z, 2))
* (f64::powi(b.x, 2)
+ f64::powi(b.y, 2)
+ f64::powi(b.z, 2)
+ 2. * a.x * c.x
+ 2. * a.y * c.y
+ 2. * a.z * c.z)
- 9. * f64::powi(a.x * b.x + a.y * b.y + a.z * b.z, 2),
3,
) + f64::powi(
-(108. * b.y * c.y * f64::powi(a.x, 4))
- 108. * b.z * c.z * f64::powi(a.x, 4)
+ 54. * b.x * f64::powi(b.y, 2) * f64::powi(a.x, 3)
+ 54. * b.x * f64::powi(b.z, 2) * f64::powi(a.x, 3)
+ 108. * c.x * a.y * b.y * f64::powi(a.x, 3)
+ 108. * b.x * a.y * c.y * f64::powi(a.x, 3)
+ 108. * c.x * a.z * b.z * f64::powi(a.x, 3)
+ 108. * b.x * a.z * c.z * f64::powi(a.x, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.x, 2)
+ 54. * a.z * f64::powi(b.z, 3) * f64::powi(a.x, 2)
- 108. * b.x * c.x * f64::powi(a.y, 2) * f64::powi(a.x, 2)
- 108. * b.x * c.x * f64::powi(a.z, 2) * f64::powi(a.x, 2)
- 216. * b.y * c.y * f64::powi(a.z, 2) * f64::powi(a.x, 2)
+ 54. * a.y * b.y * f64::powi(b.z, 2) * f64::powi(a.x, 2)
- 108. * f64::powi(b.x, 2) * a.y * b.y * f64::powi(a.x, 2)
- 108. * f64::powi(a.y, 2) * b.y * c.y * f64::powi(a.x, 2)
- 108. * f64::powi(b.x, 2) * a.z * b.z * f64::powi(a.x, 2)
+ 54. * f64::powi(b.y, 2) * a.z * b.z * f64::powi(a.x, 2)
+ 108. * a.y * c.y * a.z * b.z * f64::powi(a.x, 2)
+ 108. * a.y * b.y * a.z * c.z * f64::powi(a.x, 2)
- 216. * f64::powi(a.y, 2) * b.z * c.z * f64::powi(a.x, 2)
- 108. * f64::powi(a.z, 2) * b.z * c.z * f64::powi(a.x, 2)
+ 54. * f64::powi(b.x, 3) * f64::powi(a.y, 2) * a.x
- 108. * b.x * f64::powi(a.y, 2) * f64::powi(b.y, 2) * a.x
+ 54. * f64::powi(b.x, 3) * f64::powi(a.z, 2) * a.x
+ 54. * b.x * f64::powi(b.y, 2) * f64::powi(a.z, 2) * a.x
+ 108. * c.x * a.y * b.y * f64::powi(a.z, 2) * a.x
+ 108. * b.x * a.y * c.y * f64::powi(a.z, 2) * a.x
+ 54. * b.x * f64::powi(a.y, 2) * f64::powi(b.z, 2) * a.x
- 108. * b.x * f64::powi(a.z, 2) * f64::powi(b.z, 2) * a.x
+ 108. * c.x * f64::powi(a.y, 3) * b.y * a.x
+ 108. * b.x * f64::powi(a.y, 3) * c.y * a.x
+ 108. * c.x * f64::powi(a.z, 3) * b.z * a.x
+ 108. * c.x * f64::powi(a.y, 2) * a.z * b.z * a.x
- 324. * b.x * a.y * b.y * a.z * b.z * a.x
+ 108. * b.x * f64::powi(a.z, 3) * c.z * a.x
+ 108. * b.x * f64::powi(a.y, 2) * a.z * c.z * a.x
- 108. * b.x * c.x * f64::powi(a.y, 4)
- 108. * b.x * c.x * f64::powi(a.z, 4)
- 108. * b.y * c.y * f64::powi(a.z, 4)
+ 54. * f64::powi(a.y, 2) * a.z * f64::powi(b.z, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.z, 2)
- 216. * b.x * c.x * f64::powi(a.y, 2) * f64::powi(a.z, 2)
+ 54. * f64::powi(b.x, 2) * a.y * b.y * f64::powi(a.z, 2)
- 108. * f64::powi(a.y, 2) * b.y * c.y * f64::powi(a.z, 2)
- 108. * a.y * b.y * f64::powi(a.z, 2) * f64::powi(b.z, 2)
+ 54. * f64::powi(a.y, 3) * b.y * f64::powi(b.z, 2)
+ 54. * f64::powi(b.x, 2) * f64::powi(a.y, 3) * b.y
+ 54. * f64::powi(b.x, 2) * f64::powi(a.z, 3) * b.z
+ 54. * f64::powi(b.y, 2) * f64::powi(a.z, 3) * b.z
+ 108. * a.y * c.y * f64::powi(a.z, 3) * b.z
+ 54. * f64::powi(b.x, 2) * f64::powi(a.y, 2) * a.z * b.z
- 108. * f64::powi(a.y, 2) * f64::powi(b.y, 2) * a.z * b.z
+ 108. * f64::powi(a.y, 3) * c.y * a.z * b.z
+ 108. * a.y * b.y * f64::powi(a.z, 3) * c.z
+ 108. * f64::powi(a.y, 3) * b.y * a.z * c.z
- 108. * f64::powi(a.y, 4) * b.z * c.z
- 108. * f64::powi(a.y, 2) * f64::powi(a.z, 2) * b.z * c.z,
2,
),
),
1. / 3.,
) / (6.
* f64::powf(2., 1. / 3.)
* (f64::powi(a.x, 2) + f64::powi(a.y, 2) + f64::powi(a.z, 2)))
- (6.
* (f64::powi(a.x, 2) + f64::powi(a.y, 2) + f64::powi(a.z, 2))
* (f64::powi(b.x, 2)
+ f64::powi(b.y, 2)
+ f64::powi(b.z, 2)
+ 2. * a.x * c.x
+ 2. * a.y * c.y
+ 2. * a.z * c.z)
- 9. * f64::powi(a.x * b.x + a.y * b.y + a.z * b.z, 2))
/ (3.
* f64::powf(2., 2. / 3.)
* (f64::powi(a.x, 2) + f64::powi(a.y, 2) + f64::powi(a.z, 2))
* f64::powf(
-(108. * b.y * c.y * f64::powi(a.x, 4))
- 108. * b.z * c.z * f64::powi(a.x, 4)
+ 54. * b.x * f64::powi(b.y, 2) * f64::powi(a.x, 3)
+ 54. * b.x * f64::powi(b.z, 2) * f64::powi(a.x, 3)
+ 108. * c.x * a.y * b.y * f64::powi(a.x, 3)
+ 108. * b.x * a.y * c.y * f64::powi(a.x, 3)
+ 108. * c.x * a.z * b.z * f64::powi(a.x, 3)
+ 108. * b.x * a.z * c.z * f64::powi(a.x, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.x, 2)
+ 54. * a.z * f64::powi(b.z, 3) * f64::powi(a.x, 2)
- 108. * b.x * c.x * f64::powi(a.y, 2) * f64::powi(a.x, 2)
- 108. * b.x * c.x * f64::powi(a.z, 2) * f64::powi(a.x, 2)
- 216. * b.y * c.y * f64::powi(a.z, 2) * f64::powi(a.x, 2)
+ 54. * a.y * b.y * f64::powi(b.z, 2) * f64::powi(a.x, 2)
- 108. * f64::powi(b.x, 2) * a.y * b.y * f64::powi(a.x, 2)
- 108. * f64::powi(a.y, 2) * b.y * c.y * f64::powi(a.x, 2)
- 108. * f64::powi(b.x, 2) * a.z * b.z * f64::powi(a.x, 2)
+ 54. * f64::powi(b.y, 2) * a.z * b.z * f64::powi(a.x, 2)
+ 108. * a.y * c.y * a.z * b.z * f64::powi(a.x, 2)
+ 108. * a.y * b.y * a.z * c.z * f64::powi(a.x, 2)
- 216. * f64::powi(a.y, 2) * b.z * c.z * f64::powi(a.x, 2)
- 108. * f64::powi(a.z, 2) * b.z * c.z * f64::powi(a.x, 2)
+ 54. * f64::powi(b.x, 3) * f64::powi(a.y, 2) * a.x
- 108. * b.x * f64::powi(a.y, 2) * f64::powi(b.y, 2) * a.x
+ 54. * f64::powi(b.x, 3) * f64::powi(a.z, 2) * a.x
+ 54. * b.x * f64::powi(b.y, 2) * f64::powi(a.z, 2) * a.x
+ 108. * c.x * a.y * b.y * f64::powi(a.z, 2) * a.x
+ 108. * b.x * a.y * c.y * f64::powi(a.z, 2) * a.x
+ 54. * b.x * f64::powi(a.y, 2) * f64::powi(b.z, 2) * a.x
- 108. * b.x * f64::powi(a.z, 2) * f64::powi(b.z, 2) * a.x
+ 108. * c.x * f64::powi(a.y, 3) * b.y * a.x
+ 108. * b.x * f64::powi(a.y, 3) * c.y * a.x
+ 108. * c.x * f64::powi(a.z, 3) * b.z * a.x
+ 108. * c.x * f64::powi(a.y, 2) * a.z * b.z * a.x
- 324. * b.x * a.y * b.y * a.z * b.z * a.x
+ 108. * b.x * f64::powi(a.z, 3) * c.z * a.x
+ 108. * b.x * f64::powi(a.y, 2) * a.z * c.z * a.x
- 108. * b.x * c.x * f64::powi(a.y, 4)
- 108. * b.x * c.x * f64::powi(a.z, 4)
- 108. * b.y * c.y * f64::powi(a.z, 4)
+ 54. * f64::powi(a.y, 2) * a.z * f64::powi(b.z, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.z, 2)
- 216. * b.x * c.x * f64::powi(a.y, 2) * f64::powi(a.z, 2)
+ 54. * f64::powi(b.x, 2) * a.y * b.y * f64::powi(a.z, 2)
- 108. * f64::powi(a.y, 2) * b.y * c.y * f64::powi(a.z, 2)
- 108. * a.y * b.y * f64::powi(a.z, 2) * f64::powi(b.z, 2)
+ 54. * f64::powi(a.y, 3) * b.y * f64::powi(b.z, 2)
+ 54. * f64::powi(b.x, 2) * f64::powi(a.y, 3) * b.y
+ 54. * f64::powi(b.x, 2) * f64::powi(a.z, 3) * b.z
+ 54. * f64::powi(b.y, 2) * f64::powi(a.z, 3) * b.z
+ 108. * a.y * c.y * f64::powi(a.z, 3) * b.z
+ 54. * f64::powi(b.x, 2) * f64::powi(a.y, 2) * a.z * b.z
- 108. * f64::powi(a.y, 2) * f64::powi(b.y, 2) * a.z * b.z
+ 108. * f64::powi(a.y, 3) * c.y * a.z * b.z
+ 108. * a.y * b.y * f64::powi(a.z, 3) * c.z
+ 108. * f64::powi(a.y, 3) * b.y * a.z * c.z
- 108. * f64::powi(a.y, 4) * b.z * c.z
- 108. * f64::powi(a.y, 2) * f64::powi(a.z, 2) * b.z * c.z
+ f64::sqrt(
4. * f64::powi(
6. * (f64::powi(a.x, 2)
+ f64::powi(a.y, 2)
+ f64::powi(a.z, 2))
* (f64::powi(b.x, 2)
+ f64::powi(b.y, 2)
+ f64::powi(b.z, 2)
+ 2. * a.x * c.x
+ 2. * a.y * c.y
+ 2. * a.z * c.z)
- 9. * f64::powi(a.x * b.x + a.y * b.y + a.z * b.z, 2),
3,
) + f64::powi(
-(108. * b.y * c.y * f64::powi(a.x, 4))
- 108. * b.z * c.z * f64::powi(a.x, 4)
+ 54. * b.x * f64::powi(b.y, 2) * f64::powi(a.x, 3)
+ 54. * b.x * f64::powi(b.z, 2) * f64::powi(a.x, 3)
+ 108. * c.x * a.y * b.y * f64::powi(a.x, 3)
+ 108. * b.x * a.y * c.y * f64::powi(a.x, 3)
+ 108. * c.x * a.z * b.z * f64::powi(a.x, 3)
+ 108. * b.x * a.z * c.z * f64::powi(a.x, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.x, 2)
+ 54. * a.z * f64::powi(b.z, 3) * f64::powi(a.x, 2)
- 108.
* b.x
* c.x
* f64::powi(a.y, 2)
* f64::powi(a.x, 2)
- 108.
* b.x
* c.x
* f64::powi(a.z, 2)
* f64::powi(a.x, 2)
- 216.
* b.y
* c.y
* f64::powi(a.z, 2)
* f64::powi(a.x, 2)
+ 54.
* a.y
* b.y
* f64::powi(b.z, 2)
* f64::powi(a.x, 2)
- 108.
* f64::powi(b.x, 2)
* a.y
* b.y
* f64::powi(a.x, 2)
- 108.
* f64::powi(a.y, 2)
* b.y
* c.y
* f64::powi(a.x, 2)
- 108.
* f64::powi(b.x, 2)
* a.z
* b.z
* f64::powi(a.x, 2)
+ 54.
* f64::powi(b.y, 2)
* a.z
* b.z
* f64::powi(a.x, 2)
+ 108. * a.y * c.y * a.z * b.z * f64::powi(a.x, 2)
+ 108. * a.y * b.y * a.z * c.z * f64::powi(a.x, 2)
- 216.
* f64::powi(a.y, 2)
* b.z
* c.z
* f64::powi(a.x, 2)
- 108.
* f64::powi(a.z, 2)
* b.z
* c.z
* f64::powi(a.x, 2)
+ 54. * f64::powi(b.x, 3) * f64::powi(a.y, 2) * a.x
- 108.
* b.x
* f64::powi(a.y, 2)
* f64::powi(b.y, 2)
* a.x
+ 54. * f64::powi(b.x, 3) * f64::powi(a.z, 2) * a.x
+ 54.
* b.x
* f64::powi(b.y, 2)
* f64::powi(a.z, 2)
* a.x
+ 108. * c.x * a.y * b.y * f64::powi(a.z, 2) * a.x
+ 108. * b.x * a.y * c.y * f64::powi(a.z, 2) * a.x
+ 54.
* b.x
* f64::powi(a.y, 2)
* f64::powi(b.z, 2)
* a.x
- 108.
* b.x
* f64::powi(a.z, 2)
* f64::powi(b.z, 2)
* a.x
+ 108. * c.x * f64::powi(a.y, 3) * b.y * a.x
+ 108. * b.x * f64::powi(a.y, 3) * c.y * a.x
+ 108. * c.x * f64::powi(a.z, 3) * b.z * a.x
+ 108. * c.x * f64::powi(a.y, 2) * a.z * b.z * a.x
- 324. * b.x * a.y * b.y * a.z * b.z * a.x
+ 108. * b.x * f64::powi(a.z, 3) * c.z * a.x
+ 108. * b.x * f64::powi(a.y, 2) * a.z * c.z * a.x
- 108. * b.x * c.x * f64::powi(a.y, 4)
- 108. * b.x * c.x * f64::powi(a.z, 4)
- 108. * b.y * c.y * f64::powi(a.z, 4)
+ 54. * f64::powi(a.y, 2) * a.z * f64::powi(b.z, 3)
+ 54. * a.y * f64::powi(b.y, 3) * f64::powi(a.z, 2)
- 216.
* b.x
* c.x
* f64::powi(a.y, 2)
* f64::powi(a.z, 2)
+ 54.
* f64::powi(b.x, 2)
* a.y
* b.y
* f64::powi(a.z, 2)
- 108.
* f64::powi(a.y, 2)
* b.y
* c.y
* f64::powi(a.z, 2)
- 108.
* a.y
* b.y
* f64::powi(a.z, 2)
* f64::powi(b.z, 2)
+ 54. * f64::powi(a.y, 3) * b.y * f64::powi(b.z, 2)
+ 54. * f64::powi(b.x, 2) * f64::powi(a.y, 3) * b.y
+ 54. * f64::powi(b.x, 2) * f64::powi(a.z, 3) * b.z
+ 54. * f64::powi(b.y, 2) * f64::powi(a.z, 3) * b.z
+ 108. * a.y * c.y * f64::powi(a.z, 3) * b.z
+ 54.
* f64::powi(b.x, 2)
* f64::powi(a.y, 2)
* a.z
* b.z
- 108.
* f64::powi(a.y, 2)
* f64::powi(b.y, 2)
* a.z
* b.z
+ 108. * f64::powi(a.y, 3) * c.y * a.z * b.z
+ 108. * a.y * b.y * f64::powi(a.z, 3) * c.z
+ 108. * f64::powi(a.y, 3) * b.y * a.z * c.z
- 108. * f64::powi(a.y, 4) * b.z * c.z
- 108.
* f64::powi(a.y, 2)
* f64::powi(a.z, 2)
* b.z
* c.z,
2,
),
),
1. / 3.,
))
}
}