pub fn orient3d(
a: &[f64; 3],
b: &[f64; 3],
c: &[f64; 3],
d: &[f64; 3],
) -> Option<Sign>Expand description
The orientation of d with respect to the plane through a, b and
c: the exact sign of the determinant
| a.x - d.x a.y - d.y a.z - d.z |
| b.x - d.x b.y - d.y b.z - d.z |
| c.x - d.x c.y - d.y c.z - d.z |The sign is Sign::Positive when d lies below the plane, taking
“above” to be the side from which a, b and c appear in
counter-clockwise order; Sign::Negative when d lies above it; and
Sign::Zero when the four points are coplanar. This is the convention
of Shewchuk’s orient3d. Swapping any two points flips the sign.
§When the result is None
The result is Some whenever every nonzero coordinate has a magnitude
between 2^-188 and 2^239 (about 2.5e-57 and 8.8e71): the last
two stages evaluate with expansions, one on coordinates up to 2^238 and
the other on coordinates up to 2^239, and together they decide every
such input. Outside that range the sign is still exact when it is
returned, but None is returned when no stage can decide: always when
some coordinate is not finite, and otherwise only when the
floating-point filter and the stage on exact differences of coordinates
cannot decide either. This is provisional: a later version will decide
every finite input.
§Examples
use implicit_predicates::{Sign, orient3d};
let (a, b, c) = ([1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]);
// a, b and c appear counter-clockwise from (1, 1, 1), above the plane.
assert_eq!(orient3d(&a, &b, &c, &[1.0, 1.0, 1.0]), Some(Sign::Negative));
assert_eq!(orient3d(&a, &b, &c, &[0.0, 0.0, 0.0]), Some(Sign::Positive));
// A point on the plane, and one that is not a point.
assert_eq!(orient3d(&a, &b, &c, &[0.5, 0.25, 0.25]), Some(Sign::Zero));
assert_eq!(orient3d(&a, &b, &c, &[f64::NAN, 0.0, 0.0]), None);