Skip to main content

Point

Trait Point 

Source
pub trait Point {
    // Required methods
    fn approx(&self) -> &[f64; 3];
    fn err(&self) -> &[f64; 3];
    fn is_explicit(&self) -> bool;
    fn exact(
        &self,
        scratch: &mut Scratch<'_>,
    ) -> Result<ExactCoords, ExactError>;
}
Expand description

A point in three dimensions, as the predicates read it.

Implementations must uphold, for each axis k:

  • err()[k] is not negative (it may be +∞) and bounds the distance between approx()[k] and coordinate k of the point, x_k / w, where x_k is the numerator and w the weight that exact writes (x_k itself when w is Weight::One);
  • err()[k] is zero only when approx()[k] is that coordinate;
  • is_explicit returns true only if approx() holds the exact coordinates, err() is zero on every axis and exact gives Weight::One: for such points the predicates use approx() alone, with no uncertainty;
  • every span of the ExactCoords that exact returns holds a valid expansion (see expansion: nonzero components of strictly increasing magnitude that do not overlap), written in the arena it was given;
  • exact leaves the arena below the top it had when exact was called as it was: it writes only above that top and never resets the arena to a mark taken before the call, since a predicate keeps the exact coordinates of the points it read before there;
  • while a predicate runs, which may call each method more than once, approx, err and is_explicit give the same answer every time and exact the same coordinates: a type with interior mutability must not change them in the middle of a call.

A predicate given a point that breaks this contract can return a wrong sign: predicates do not check it.

§Examples

use implicit_predicates_core::{Point, Scratch, Weight};

let p = [1.5, 0.0, -2.0];
assert!(p.is_explicit());
assert_eq!(p.err(), &[0.0; 3]);

let mut buf = [0.0; 3];
let mut scratch = Scratch::borrowed(&mut buf);
let exact = p.exact(&mut scratch)?;
assert_eq!(scratch.get(exact.x), &[1.5]);
assert!(exact.y.is_empty()); // zero
assert_eq!(exact.w, Weight::One);

Required Methods§

Source

fn approx(&self) -> &[f64; 3]

Returns an approximation of the coordinates.

Source

fn err(&self) -> &[f64; 3]

Returns, per coordinate, a bound on the error of approx.

Source

fn is_explicit(&self) -> bool

Whether the point is explicit. It may return true only if approx holds the exact coordinates, every err is zero and exact gives Weight::One; returning false is always allowed. A wrong true makes the predicates return wrong signs, unchecked.

Source

fn exact(&self, scratch: &mut Scratch<'_>) -> Result<ExactCoords, ExactError>

Writes the exact coordinates as expansions in scratch: the point is (x / w, y / w, z / w). Every span returned must hold a valid expansion of scratch (see expansion); predicates rely on it without checking it.

§Errors
  • ExactError::Exhausted if scratch runs out of room;
  • ExactError::OutOfRange if the inputs of the point lie outside the range in which its exact coordinates can be computed: they are not finite, or a product they need leaves the product domain of eft.

After an error, scratch may hold partial results above the top it had before the call; resetting to a mark taken before the call releases them.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl Point for [f64; 3]

An explicit point, not validated: its components are its exact coordinates. A component that is not finite makes exact fail with ExactError::OutOfRange.

Source§

fn exact(&self, scratch: &mut Scratch<'_>) -> Result<ExactCoords, ExactError>

Writes each coordinate as an expansion of one component, or none for zero, with Weight::One. Needs up to 3 free components; on an error the arena is unchanged.

Source§

fn approx(&self) -> &[f64; 3]

Source§

fn err(&self) -> &[f64; 3]

Source§

fn is_explicit(&self) -> bool

Implementors§