Skip to main content

orient3d

Function orient3d 

Source
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);