use crate::maths::{
line::{
closest_points_on_lines, shortest_distance_from_point_to_line_segment_squared,
shortest_distance_from_point_to_line_segment_squared_vec,
},
vec::Vec3,
};
const TRIANGLE_VERTEX_COUNT: usize = 3;
const EPSILON: f64 = 1e-15;
pub fn longest_distance_between_line_segment_and_triangle_squared(
line_start: &[f32; 3],
line_end: &[f32; 3],
triangle_a: &[f32; 3],
triangle_b: &[f32; 3],
triangle_c: &[f32; 3],
) -> f64 {
let line_start_distance = shortest_distance_from_point_to_triangle_squared(
line_start, triangle_a, triangle_b, triangle_c,
);
let line_end_distance = shortest_distance_from_point_to_triangle_squared(
line_end, triangle_a, triangle_b, triangle_c,
);
return line_start_distance.max(line_end_distance);
}
pub fn longest_distance_between_triangle_and_line_segment_squared(
triangle_a: &[f32; 3],
triangle_b: &[f32; 3],
triangle_c: &[f32; 3],
line_start: &[f32; 3],
line_end: &[f32; 3],
) -> f64 {
let triangle_a_distance =
shortest_distance_from_point_to_line_segment_squared(triangle_a, line_start, line_end);
let triangle_b_distance =
shortest_distance_from_point_to_line_segment_squared(triangle_b, line_start, line_end);
let triangle_c_distance =
shortest_distance_from_point_to_line_segment_squared(triangle_c, line_start, line_end);
return triangle_a_distance
.max(triangle_b_distance)
.max(triangle_c_distance);
}
pub fn longest_distance_between_triangles_squared(
a_a: &[f32; 3],
a_b: &[f32; 3],
a_c: &[f32; 3],
b_a: &[f32; 3],
b_b: &[f32; 3],
b_c: &[f32; 3],
) -> f64 {
let a_a_distance = shortest_distance_from_point_to_triangle_squared(a_a, b_a, b_b, b_c);
let a_b_distance = shortest_distance_from_point_to_triangle_squared(a_b, b_a, b_b, b_c);
let a_c_distance = shortest_distance_from_point_to_triangle_squared(a_c, b_a, b_b, b_c);
return a_a_distance.max(a_b_distance).max(a_c_distance);
}
pub fn shortest_distance_from_point_to_triangle_squared(
point: &[f32; 3],
triangle_a: &[f32; 3],
triangle_b: &[f32; 3],
triangle_c: &[f32; 3],
) -> f64 {
let point = Vec3::from_array(point);
let triangle = [
Vec3::from_array(triangle_a),
Vec3::from_array(triangle_b),
Vec3::from_array(triangle_c),
];
if let Some(distance_to_plane) =
get_point_projected_to_triangle_distance_squared_if_inside(point, &triangle)
{
return distance_to_plane;
}
let point_to_ab =
shortest_distance_from_point_to_line_segment_squared_vec(point, triangle[0], triangle[1]);
let point_to_bc =
shortest_distance_from_point_to_line_segment_squared_vec(point, triangle[1], triangle[2]);
let point_to_ca =
shortest_distance_from_point_to_line_segment_squared_vec(point, triangle[2], triangle[0]);
return point_to_ab.min(point_to_bc).min(point_to_ca);
}
fn get_point_projected_to_triangle_distance_squared_if_inside(
point: Vec3,
triangle: &[Vec3; 3],
) -> Option<f64> {
let ab = triangle[1] - triangle[0];
let ac = triangle[2] - triangle[0];
let ap = point - triangle[0];
let normal = ab.cross(&ac).normalize();
let distance_to_plane = ap.dot(&normal);
let projected_point = point - normal * distance_to_plane;
let a_to_projected_point = projected_point - triangle[0];
let d00 = ab.dot(&ab);
let d01 = ab.dot(&ac);
let d11 = ac.dot(&ac);
let d20 = a_to_projected_point.dot(&ab);
let d21 = a_to_projected_point.dot(&ac);
let denom = d00 * d11 - d01 * d01;
let u = (d11 * d20 - d01 * d21) / denom;
let v = (d00 * d21 - d01 * d20) / denom;
if u >= 0.0 && v >= 0.0 && u + v <= 1.0 {
return Some(distance_to_plane.powi(2));
}
return None;
}
pub fn shortest_distance_from_line_segment_to_triangle_squared(
line_start: &[f32; 3],
line_end: &[f32; 3],
triangle_a: &[f32; 3],
triangle_b: &[f32; 3],
triangle_c: &[f32; 3],
) -> f64 {
let p = Vec3::from_array(line_start);
let q = Vec3::from_array(line_end);
let triangle = [
Vec3::from_array(triangle_a),
Vec3::from_array(triangle_b),
Vec3::from_array(triangle_c),
];
let pq = q - p;
let ab = triangle[1] - triangle[0];
let ac = triangle[2] - triangle[0];
let bc = triangle[2] - triangle[1];
let ap = p - triangle[0];
let aq = q - triangle[0];
let ab_dot_ab = ab.dot(&ab);
let ab_dot_ac = ab.dot(&ac);
let ac_dot_ac = ac.dot(&ac);
let barycentric_denominator = ab_dot_ab * ac_dot_ac - ab_dot_ac * ab_dot_ac;
let reciprocal_barycentric_denominator = if barycentric_denominator > 0.0 {
1.0 / barycentric_denominator
} else {
0.0
};
let triangle_normal = ab.cross(&ac).normalize();
let p_distance_to_plane = ap.dot(&triangle_normal);
let q_distance_to_plane = aq.dot(&triangle_normal);
if p_distance_to_plane * q_distance_to_plane <= 0.0 {
let t = -ap.dot(&triangle_normal) / pq.dot(&triangle_normal);
let intersection_point = p + t * pq;
let intersection_to_a = intersection_point - triangle[0];
let intersection_dot_ab = intersection_to_a.dot(&ab);
let intersection_dot_ac = intersection_to_a.dot(&ac);
let barycentric_v = ac_dot_ac * intersection_dot_ab
- ab_dot_ac * intersection_dot_ac * reciprocal_barycentric_denominator;
let barycentric_w = ab_dot_ab * intersection_dot_ac
- ab_dot_ab * intersection_dot_ab * reciprocal_barycentric_denominator;
if barycentric_v >= 0.0 && barycentric_w >= 0.0 && barycentric_v + barycentric_w <= 1.0 {
return 0.0;
}
}
let edge_closest_points = [
closest_points_on_lines(triangle[0], triangle[1], p, q), closest_points_on_lines(triangle[1], triangle[2], p, q), closest_points_on_lines(triangle[2], triangle[0], p, q), ];
let closest_edge_distance = edge_closest_points
.iter()
.map(|(a, b)| (*a - *b).length_squared())
.min_by(|a, b| a.total_cmp(b))
.expect("Tried to compare a NaN value, this should never happen unless a vertex was NaN");
let p_distance_to_face_if_projects_inside =
get_point_projected_to_triangle_distance_squared_if_inside(p, &triangle);
let q_distance_to_face_if_projects_inside =
get_point_projected_to_triangle_distance_squared_if_inside(q, &triangle);
let shortest_distance = [
closest_edge_distance,
p_distance_to_face_if_projects_inside.unwrap_or(f64::INFINITY),
q_distance_to_face_if_projects_inside.unwrap_or(f64::INFINITY),
]
.into_iter()
.min_by(|a, b| a.total_cmp(b))
.expect("Tried to compare a NaN value, this should never happen unless a vertex was NaN");
return shortest_distance;
}
pub fn shortest_triangle_distance_squared(
a_a: &[f32; 3],
a_b: &[f32; 3],
a_c: &[f32; 3],
b_a: &[f32; 3],
b_b: &[f32; 3],
b_c: &[f32; 3],
) -> f64 {
let triangle_a = [
Vec3::from_array(a_a),
Vec3::from_array(a_b),
Vec3::from_array(a_c),
];
let triangle_b = [
Vec3::from_array(b_a),
Vec3::from_array(b_b),
Vec3::from_array(b_c),
];
let edges_a = [
triangle_a[1] - triangle_a[0],
triangle_a[2] - triangle_a[1],
triangle_a[0] - triangle_a[2],
];
let edges_b = [
triangle_b[1] - triangle_b[0],
triangle_b[2] - triangle_b[1],
triangle_b[0] - triangle_b[2],
];
let mut min_distance_closest_point_a: Vec3 = Vec3::new(0.0, 0.0, 0.0);
let mut min_distance_closest_point_b: Vec3 = Vec3::new(0.0, 0.0, 0.0);
let mut min_squared_distance = f64::INFINITY;
let mut triangles_are_separated = false;
for i in 0..TRIANGLE_VERTEX_COUNT {
for j in 0..TRIANGLE_VERTEX_COUNT {
let (closest_on_a, closest_on_b) = closest_points_on_lines(
triangle_a[i],
triangle_a[(i + 1) % TRIANGLE_VERTEX_COUNT],
triangle_b[j],
triangle_b[(j + 1) % TRIANGLE_VERTEX_COUNT],
);
let vec_between_closest_points = closest_on_b - closest_on_a;
let squared_distance = vec_between_closest_points.length_squared();
if squared_distance <= min_squared_distance {
min_squared_distance = squared_distance;
min_distance_closest_point_a = closest_on_a;
min_distance_closest_point_b = closest_on_b;
let third_triangle_vertex_a = triangle_a[(i + 2) % TRIANGLE_VERTEX_COUNT];
let vec_to_third_triangle_vertex_a =
third_triangle_vertex_a - min_distance_closest_point_a;
let mut dot_a = vec_to_third_triangle_vertex_a.dot(&vec_between_closest_points);
let third_triangle_vertex_b = triangle_b[(j + 2) % TRIANGLE_VERTEX_COUNT];
let vec_to_third_triangle_vertex_b =
third_triangle_vertex_b - min_distance_closest_point_b;
let mut dot_b = vec_to_third_triangle_vertex_b.dot(&vec_between_closest_points);
if dot_a <= 0.0 && dot_b >= 0.0 {
return min_squared_distance;
}
dot_a = dot_a.max(0.0); dot_b = dot_b.min(0.0);
if (min_squared_distance - dot_a + dot_b) > 0.0 {
triangles_are_separated = true;
}
}
}
}
let maybe_shortest_distance = maybe_shortest_distance_between_face_of_a_and_vertex_of_b(
&triangle_a,
&triangle_b,
&edges_a,
);
if let Some(closest_point_on_a) = maybe_shortest_distance.closest_point_found_on_a
&& let Some(closest_point_on_b) = maybe_shortest_distance.closest_point_found_on_b
{
return (closest_point_on_a - closest_point_on_b).length_squared();
}
triangles_are_separated = triangles_are_separated || maybe_shortest_distance.separated;
let maybe_shortest_distance = maybe_shortest_distance_between_face_of_a_and_vertex_of_b(
&triangle_b,
&triangle_a,
&edges_b,
);
if let Some(closest_point_on_a) = maybe_shortest_distance.closest_point_found_on_a
&& let Some(closest_point_on_b) = maybe_shortest_distance.closest_point_found_on_b
{
return (closest_point_on_a - closest_point_on_b).length_squared();
}
triangles_are_separated = triangles_are_separated || maybe_shortest_distance.separated;
if triangles_are_separated {
return (min_distance_closest_point_a - min_distance_closest_point_b).length_squared();
}
return 0.0;
}
struct MaybeShortestDistanceBetweenFaceOfAAndVertexOfB {
closest_point_found_on_a: Option<Vec3>,
closest_point_found_on_b: Option<Vec3>,
separated: bool,
}
fn maybe_shortest_distance_between_face_of_a_and_vertex_of_b(
triangle_a: &[Vec3; 3],
triangle_b: &[Vec3; 3],
edges_a: &[Vec3; 3],
) -> MaybeShortestDistanceBetweenFaceOfAAndVertexOfB {
let normal_a = edges_a[0].cross(&edges_a[1]);
let squared_normal_length = normal_a.length_squared();
let mut triangles_are_separated = false;
if squared_normal_length > EPSILON {
let signed_distances_to_plane_a = [
(triangle_a[0] - triangle_b[0]).dot(&normal_a),
(triangle_a[0] - triangle_b[1]).dot(&normal_a),
(triangle_a[0] - triangle_b[2]).dot(&normal_a),
];
let all_positive = signed_distances_to_plane_a.iter().all(|&d| d > 0.0);
let all_negative = signed_distances_to_plane_a.iter().all(|&d| d < 0.0);
if all_positive || all_negative {
triangles_are_separated = true;
let closest_index_on_b = signed_distances_to_plane_a
.iter()
.enumerate()
.min_by(|(_, a), &(_, b)| a.abs().total_cmp(&b.abs()))
.map(|(index, _)| index)
.expect("Tried to compare a NaN value, this should never happen unless a vertex was NaN");
let closest_vertex_on_b = triangle_b[closest_index_on_b];
let mut is_inside = true;
for i in 0..TRIANGLE_VERTEX_COUNT {
let edge_plane_normal = normal_a.cross(&edges_a[i]);
let vec_to_vertex = closest_vertex_on_b - triangle_a[i];
if vec_to_vertex.dot(&edge_plane_normal) <= 0.0 {
is_inside = false;
break;
}
}
if is_inside {
let closest_point_on_a = closest_vertex_on_b
+ normal_a
* (signed_distances_to_plane_a[closest_index_on_b] / squared_normal_length);
let closest_point_on_b = closest_vertex_on_b;
return MaybeShortestDistanceBetweenFaceOfAAndVertexOfB {
closest_point_found_on_a: Some(closest_point_on_a),
closest_point_found_on_b: Some(closest_point_on_b),
separated: triangles_are_separated,
};
}
}
}
return MaybeShortestDistanceBetweenFaceOfAAndVertexOfB {
closest_point_found_on_a: None,
closest_point_found_on_b: None,
separated: triangles_are_separated,
};
}
mod tests {
use super::*;
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_point_is_a_vertex() {
let point = [0.0, 0.0, 0.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 0.0);
}
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_point_is_on_an_edge() {
let point = [0.5, 0.0, 0.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 0.0);
}
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_point_is_inside_the_triangle() {
let point = [0.2, 0.2, 0.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 0.0);
}
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_coplanar_point_is_outside_triangle_closest_to_vertex()
{
let point = [2.0, 0.0, 0.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_coplanar_point_is_outside_triangle_closest_to_edge()
{
let point = [0.5, -1.0, 0.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_point_projects_inside_triangle()
{
let point = [0.2, 0.2, 1.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_point_projects_outside_triangle_closest_to_vertex()
{
let point = [4.0, 0.0, 4.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 5.0);
}
#[test]
fn test_shortest_distance_from_point_to_triangle_squared_where_point_projects_outside_triangle_closest_to_edge()
{
let point = [0.5, -3.0, 4.0];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_point_to_triangle_squared(
&point,
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 5.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_is_an_edge() {
let segment = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 0.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_is_a_vertex() {
let segment = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 0.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_parallel() {
let segment = [[-1.0, 0.0, 1.0], [2.0, 0.0, 1.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_projects_inside_triangle()
{
let segment = [[0.4, 0.2, 1.0], [0.6, 0.2, 1.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_vertex_projects_inside_triangle()
{
let segment = [[0.4, 0.2, 1.0], [2.0, 0.2, 3.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_edge_closest_to_triangle_vertex()
{
let segment = [[-1.0, 2.0, 0.0], [1.0, 2.0, 0.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_edge_closest_to_triangle_edge()
{
let segment = [[-1.0, -1.0, 0.0], [1.0, -1.0, 0.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_vertex_closest_to_triangle_vertex()
{
let segment = [[2.0, 0.0, 0.0], [4.0, 0.0, 0.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_distance_from_line_segment_to_triangle_squared_where_segment_vertex_closest_to_triangle_edge()
{
let segment = [[0.5, -1.0, 0.0], [0.5, -2.0, 0.0]];
let triangle = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
let distance = shortest_distance_from_line_segment_to_triangle_squared(
&segment[0],
&segment[1],
&triangle[0],
&triangle[1],
&triangle[2],
);
assert_eq!(distance.sqrt(), 1.0);
}
#[test]
fn test_shortest_triangle_distance_where_vertex_is_closest() {
let a_a = [0.0, 0.0, 0.0];
let a_b = [0.0, 1.0, 0.0];
let a_c = [1.0, 0.5, 0.0];
let b_a = [10.0, 0.0, 0.0];
let b_b = [10.0, 1.0, 0.0];
let b_c = [9.0, 0.5, 0.0];
let distance = shortest_triangle_distance_squared(&a_a, &a_b, &a_c, &b_a, &b_b, &b_c);
assert_eq!(distance.sqrt(), 8.0);
}
#[test]
fn test_shortest_triangle_distance_where_edge_is_closest() {
let a_a = [0.0, 0.0, 0.0];
let a_b = [1.0, 1.0, 0.0];
let a_c = [1.0, 0.0, 0.0];
let b_a = [10.0, 0.0, 0.0];
let b_b = [9.0, 1.0, 0.0];
let b_c = [9.0, 0.0, 0.0];
let distance = shortest_triangle_distance_squared(&a_a, &a_b, &a_c, &b_a, &b_b, &b_c);
assert_eq!(distance.sqrt(), 8.0);
}
#[test]
fn test_shortest_triangle_distance_with_identical_triangles() {
let a_a = [0.0, 0.0, 0.0];
let a_b = [1.0, 0.0, 0.0];
let a_c = [0.0, 1.0, 0.0];
let b_a = [0.0, 0.0, 0.0];
let b_b = [1.0, 0.0, 0.0];
let b_c = [0.0, 1.0, 0.0];
let distance = shortest_triangle_distance_squared(&a_a, &a_b, &a_c, &b_a, &b_b, &b_c);
assert_eq!(distance.sqrt(), 0.0);
}
#[test]
fn test_shortest_triangle_distance_with_coplanar_triangles() {
let a_a = [0.0, 0.0, 0.0];
let a_b = [1.0, 0.0, 0.0];
let a_c = [0.0, 1.0, 0.0];
let b_a = [5.0, 0.0, 0.0];
let b_b = [6.0, 0.0, 0.0];
let b_c = [5.0, 6.0, 0.0];
let distance = shortest_triangle_distance_squared(&a_a, &a_b, &a_c, &b_a, &b_b, &b_c);
assert_eq!(distance.sqrt(), 4.0);
}
#[test]
fn test_shortest_triangle_distance_with_triangles_that_are_parallel() {
let a_a = [0.0, 0.0, 0.0];
let a_b = [1.0, 0.0, 0.0];
let a_c = [0.0, 1.0, 0.0];
let b_a = [0.0, 0.0, 3.0];
let b_b = [1.0, 0.0, 3.0];
let b_c = [0.0, 1.0, 3.0];
let distance = shortest_triangle_distance_squared(&a_a, &a_b, &a_c, &b_a, &b_b, &b_c);
assert_eq!(distance.sqrt(), 3.0);
}
}