mirror of
https://github.com/hannobraun/Fornjot
synced 2025-01-07 16:57:32 +00:00
Merge pull request #214 from hannobraun/scalar
Implement/derive same set of traits for most math types
This commit is contained in:
commit
96ef770686
@ -3,6 +3,7 @@ use parry3d_f64::bounding_volume::BoundingVolume as _;
|
|||||||
use super::{Point, Vector};
|
use super::{Point, Vector};
|
||||||
|
|
||||||
/// An axis-aligned bounding box (AABB)
|
/// An axis-aligned bounding box (AABB)
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub struct Aabb<const D: usize> {
|
pub struct Aabb<const D: usize> {
|
||||||
/// The minimum coordinates of the AABB
|
/// The minimum coordinates of the AABB
|
||||||
pub min: Point<D>,
|
pub min: Point<D>,
|
||||||
|
@ -12,7 +12,7 @@ use super::{Scalar, Vector};
|
|||||||
///
|
///
|
||||||
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
||||||
/// easier to work with vectors. This is a work in progress.
|
/// easier to work with vectors. This is a work in progress.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub struct Point<const D: usize>([Scalar; D]);
|
pub struct Point<const D: usize>([Scalar; D]);
|
||||||
|
|
||||||
impl<const D: usize> Point<D> {
|
impl<const D: usize> Point<D> {
|
||||||
|
@ -1,8 +1,31 @@
|
|||||||
use std::{cmp, f64::consts::PI, ops};
|
use std::{cmp, f64::consts::PI, hash::Hash, ops};
|
||||||
|
|
||||||
use approx::AbsDiffEq;
|
use approx::AbsDiffEq;
|
||||||
|
|
||||||
/// A scalar
|
/// A rational, finite scalar value
|
||||||
|
///
|
||||||
|
/// This is a wrapper around `f64`. On construction, it checks that the `f64`
|
||||||
|
/// value is neither infinite nor NaN. This allows `Scalar` to provide
|
||||||
|
/// implementations of [`Eq`], [`Ord`], and [`Hash`], enabling `Scalar` (and
|
||||||
|
/// types built on top of it), to be used as keys in hash maps, hash sets, and
|
||||||
|
/// similar types.
|
||||||
|
///
|
||||||
|
/// # Failing `From`/`Into` implementations
|
||||||
|
///
|
||||||
|
/// Please note that the [`From`]/[`Into`] implementation that convert floating
|
||||||
|
/// point numbers into `Scalar` can panic. These conversions call
|
||||||
|
/// [`Scalar::from_f64`] internally and panic under the same conditions.
|
||||||
|
///
|
||||||
|
/// This explicitly goes against the mandate of [`From`]/[`Into`], whose
|
||||||
|
/// documentation mandate that implementations must not fail. This is a
|
||||||
|
/// deliberate design decision. The intended use case of `Scalar` is math code
|
||||||
|
/// that considers non-finite floating point values a bug, not a recoverable
|
||||||
|
/// error.
|
||||||
|
///
|
||||||
|
/// For this use case, having easy conversions available is an advantage, and
|
||||||
|
/// explicit `unwrap`/`expect` calls would add nothing. In addition, the mandate
|
||||||
|
/// not to fail is not motivated in any way, in the [`From`]/[`Into`]
|
||||||
|
/// documentation.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub struct Scalar(f64);
|
pub struct Scalar(f64);
|
||||||
|
|
||||||
@ -23,8 +46,15 @@ impl Scalar {
|
|||||||
pub const PI: Self = Self(PI);
|
pub const PI: Self = Self(PI);
|
||||||
|
|
||||||
/// Construct a `Scalar` from an `f64`
|
/// Construct a `Scalar` from an `f64`
|
||||||
|
///
|
||||||
|
/// Panics, if `scalar` is infinite or NaN.
|
||||||
pub fn from_f64(scalar: f64) -> Self {
|
pub fn from_f64(scalar: f64) -> Self {
|
||||||
Self(scalar)
|
if scalar.is_finite() {
|
||||||
|
// `scalar` is neither infinite, nor NaN
|
||||||
|
Self(scalar)
|
||||||
|
} else {
|
||||||
|
panic!("Invalid scalar value: {scalar}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a `Scalar` from a `u64`
|
/// Construct a `Scalar` from a `u64`
|
||||||
@ -79,6 +109,22 @@ impl Scalar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Eq for Scalar {}
|
||||||
|
|
||||||
|
impl Ord for Scalar {
|
||||||
|
fn cmp(&self, other: &Self) -> cmp::Ordering {
|
||||||
|
// Should never panic, as `from_f64` checks that the wrapped value is
|
||||||
|
// finite.
|
||||||
|
self.partial_cmp(&other).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hash for Scalar {
|
||||||
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||||
|
self.0.to_bits().hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<f32> for Scalar {
|
impl From<f32> for Scalar {
|
||||||
fn from(scalar: f32) -> Self {
|
fn from(scalar: f32) -> Self {
|
||||||
Self::from_f64(scalar as f64)
|
Self::from_f64(scalar as f64)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::Point;
|
use super::Point;
|
||||||
|
|
||||||
/// A line segment, defined by its two end points
|
/// A line segment, defined by its two end points
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub struct Segment<const D: usize> {
|
pub struct Segment<const D: usize> {
|
||||||
pub a: Point<D>,
|
pub a: Point<D>,
|
||||||
pub b: Point<D>,
|
pub b: Point<D>,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::Point;
|
use super::Point;
|
||||||
|
|
||||||
/// A triangle
|
/// A triangle
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub struct Triangle {
|
pub struct Triangle {
|
||||||
pub a: Point<3>,
|
pub a: Point<3>,
|
||||||
pub b: Point<3>,
|
pub b: Point<3>,
|
||||||
|
@ -12,7 +12,7 @@ use super::Scalar;
|
|||||||
///
|
///
|
||||||
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
/// The goal of this type is to eventually implement `Eq` and `Hash`, making it
|
||||||
/// easier to work with vectors. This is a work in progress.
|
/// easier to work with vectors. This is a work in progress.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub struct Vector<const D: usize>([Scalar; D]);
|
pub struct Vector<const D: usize>([Scalar; D]);
|
||||||
|
|
||||||
impl<const D: usize> Vector<D> {
|
impl<const D: usize> Vector<D> {
|
||||||
|
Loading…
Reference in New Issue
Block a user