Inherit Zero and One for core structural traits
This commit is contained in:
parent
54adacc2a8
commit
6b48236cb6
5 changed files with 131 additions and 73 deletions
17
src/angle.rs
17
src/angle.rs
|
@ -71,19 +71,22 @@ macro_rules! impl_angle {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Angle for $Angle<S> {
|
||||
type Unitless = S;
|
||||
|
||||
impl<S: BaseFloat> Zero for $Angle<S> {
|
||||
#[inline]
|
||||
fn zero() -> $Angle<S> {
|
||||
$Angle::new(S::zero())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
$Angle::approx_eq(self, &$Angle::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Angle for $Angle<S> {
|
||||
type Unitless = S;
|
||||
|
||||
#[inline] fn full_turn() -> $Angle<S> { $Angle::new(cast($full_turn).unwrap()) }
|
||||
#[inline] fn turn_div_2() -> $Angle<S> { let factor: S = cast(2).unwrap(); $Angle::full_turn() / factor }
|
||||
#[inline] fn turn_div_3() -> $Angle<S> { let factor: S = cast(3).unwrap(); $Angle::full_turn() / factor }
|
||||
#[inline] fn turn_div_4() -> $Angle<S> { let factor: S = cast(4).unwrap(); $Angle::full_turn() / factor }
|
||||
#[inline] fn turn_div_6() -> $Angle<S> { let factor: S = cast(6).unwrap(); $Angle::full_turn() / factor }
|
||||
|
||||
#[inline] fn sin(self) -> S { Rad::from(self).s.sin() }
|
||||
#[inline] fn cos(self) -> S { Rad::from(self).s.cos() }
|
||||
|
|
|
@ -266,30 +266,34 @@ impl<S: BaseFloat> Matrix4<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Matrix2<S> {
|
||||
type Scalar = S;
|
||||
|
||||
impl<S: BaseFloat> Zero for Matrix2<S> {
|
||||
#[inline]
|
||||
fn zero() -> Matrix2<S> {
|
||||
Matrix2::new(S::zero(), S::zero(),
|
||||
S::zero(), S::zero())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
Matrix2::approx_eq(self, &Matrix2::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Matrix3<S> {
|
||||
type Scalar = S;
|
||||
|
||||
impl<S: BaseFloat> Zero for Matrix3<S> {
|
||||
#[inline]
|
||||
fn zero() -> Matrix3<S> {
|
||||
Matrix3::new(S::zero(), S::zero(), S::zero(),
|
||||
S::zero(), S::zero(), S::zero(),
|
||||
S::zero(), S::zero(), S::zero())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
Matrix3::approx_eq(self, &Matrix3::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Matrix4<S> {
|
||||
type Scalar = S;
|
||||
|
||||
impl<S: BaseFloat> Zero for Matrix4<S> {
|
||||
#[inline]
|
||||
fn zero() -> Matrix4<S> {
|
||||
Matrix4::new(S::zero(), S::zero(), S::zero(), S::zero(),
|
||||
|
@ -297,6 +301,44 @@ impl<S: BaseFloat> VectorSpace for Matrix4<S> {
|
|||
S::zero(), S::zero(), S::zero(), S::zero(),
|
||||
S::zero(), S::zero(), S::zero(), S::zero())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
Matrix4::approx_eq(self, &Matrix4::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> One for Matrix2<S> {
|
||||
#[inline]
|
||||
fn one() -> Matrix2<S> {
|
||||
Matrix2::from_value(S::one())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> One for Matrix3<S> {
|
||||
#[inline]
|
||||
fn one() -> Matrix3<S> {
|
||||
Matrix3::from_value(S::one())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> One for Matrix4<S> {
|
||||
#[inline]
|
||||
fn one() -> Matrix4<S> {
|
||||
Matrix4::from_value(S::one())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Matrix2<S> {
|
||||
type Scalar = S;
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Matrix3<S> {
|
||||
type Scalar = S;
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Matrix4<S> {
|
||||
type Scalar = S;
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> Matrix for Matrix2<S> {
|
||||
|
@ -349,11 +391,6 @@ impl<S: BaseFloat> SquareMatrix for Matrix2<S> {
|
|||
S::zero(), value.y)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn identity() -> Matrix2<S> {
|
||||
Matrix2::from_value(S::one())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transpose_self(&mut self) {
|
||||
self.swap_elements((0, 1), (1, 0));
|
||||
|
@ -450,11 +487,6 @@ impl<S: BaseFloat> SquareMatrix for Matrix3<S> {
|
|||
S::zero(), S::zero(), value.z)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn identity() -> Matrix3<S> {
|
||||
Matrix3::from_value(S::one())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn transpose_self(&mut self) {
|
||||
self.swap_elements((0, 1), (1, 0));
|
||||
|
@ -567,11 +599,6 @@ impl<S: BaseFloat> SquareMatrix for Matrix4<S> {
|
|||
S::zero(), S::zero(), S::zero(), value.w)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn identity() -> Matrix4<S> {
|
||||
Matrix4::from_value(S::one())
|
||||
}
|
||||
|
||||
fn transpose_self(&mut self) {
|
||||
self.swap_elements((0, 1), (1, 0));
|
||||
self.swap_elements((0, 2), (2, 0));
|
||||
|
|
|
@ -120,13 +120,20 @@ impl<S: BaseFloat> Quaternion<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Quaternion<S> {
|
||||
type Scalar = S;
|
||||
|
||||
impl<S: BaseFloat> Zero for Quaternion<S> {
|
||||
#[inline]
|
||||
fn zero() -> Quaternion<S> {
|
||||
Quaternion::from_sv(S::zero(), Vector3::zero())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_zero(&self) -> bool {
|
||||
Quaternion::approx_eq(self, &Quaternion::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> VectorSpace for Quaternion<S> {
|
||||
type Scalar = S;
|
||||
}
|
||||
|
||||
impl<S: BaseFloat> MetricSpace for Quaternion<S> {
|
||||
|
|
|
@ -122,6 +122,17 @@ pub trait ElementWise<Rhs = Self> {
|
|||
/// let reversed_velocity0 = -velocity0;
|
||||
/// ```
|
||||
///
|
||||
/// Vector spaces are also required to implement the additive identity trait,
|
||||
/// `Zero`. Adding this to another vector should have no effect:
|
||||
///
|
||||
/// ```rust
|
||||
/// use cgmath::prelude::*;
|
||||
/// use cgmath::Vector2;
|
||||
///
|
||||
/// let v = Vector2::new(1, 2);
|
||||
/// assert_eq!(v + Vector2::zero(), v);
|
||||
/// ```
|
||||
///
|
||||
/// ## Scalar multiplication
|
||||
///
|
||||
/// Vectors can be multiplied or divided by their associated scalars via the
|
||||
|
@ -141,6 +152,8 @@ pub trait ElementWise<Rhs = Self> {
|
|||
/// let downscaled_translation = translation / scale_factor;
|
||||
/// ```
|
||||
pub trait VectorSpace: Copy + Clone where
|
||||
Self: Zero,
|
||||
|
||||
Self: Add<Self, Output = Self>,
|
||||
Self: Sub<Self, Output = Self>,
|
||||
|
||||
|
@ -151,19 +164,6 @@ pub trait VectorSpace: Copy + Clone where
|
|||
{
|
||||
/// The associated scalar.
|
||||
type Scalar: BaseNum;
|
||||
|
||||
/// The additive identity.
|
||||
///
|
||||
/// Adding this to another `Self` value has no effect.
|
||||
///
|
||||
/// ```rust
|
||||
/// use cgmath::prelude::*;
|
||||
/// use cgmath::Vector2;
|
||||
///
|
||||
/// let v = Vector2::new(1, 2);
|
||||
/// assert_eq!(v + Vector2::zero(), v);
|
||||
/// ```
|
||||
fn zero() -> Self;
|
||||
}
|
||||
|
||||
/// A type with a distance function between values.
|
||||
|
@ -454,6 +454,8 @@ pub trait Matrix: VectorSpace where
|
|||
pub trait SquareMatrix where
|
||||
Self::Scalar: BaseFloat,
|
||||
|
||||
Self: One,
|
||||
|
||||
Self: Matrix<
|
||||
// FIXME: Can be cleaned up once equality constraints in where clauses are implemented
|
||||
Column = <Self as SquareMatrix>::ColumnRow,
|
||||
|
@ -476,9 +478,18 @@ pub trait SquareMatrix where
|
|||
/// Create a matrix from a non-uniform scale
|
||||
fn from_diagonal(diagonal: Self::ColumnRow) -> Self;
|
||||
|
||||
/// The [identity matrix](https://en.wikipedia.org/wiki/Identity_matrix). Multiplying this
|
||||
/// matrix with another has no effect.
|
||||
fn identity() -> Self;
|
||||
/// The [identity matrix]. Multiplying this matrix with another should have
|
||||
/// no effect.
|
||||
///
|
||||
/// Note that this is exactly the same as `One::one`. The term 'identity
|
||||
/// matrix' is more common though, so we provide this method as an
|
||||
/// alternative.
|
||||
///
|
||||
/// [identity matrix]: https://en.wikipedia.org/wiki/Identity_matrix
|
||||
#[inline]
|
||||
fn identity() -> Self {
|
||||
Self::one()
|
||||
}
|
||||
|
||||
/// Transpose this matrix in-place.
|
||||
fn transpose_self(&mut self);
|
||||
|
@ -534,6 +545,8 @@ pub trait Angle where
|
|||
// FIXME: Ugly type signatures - blocked by rust-lang/rust#24092
|
||||
Self: ApproxEq<Epsilon = <Self as Angle>::Unitless>,
|
||||
|
||||
Self: Zero,
|
||||
|
||||
Self: Neg<Output = Self>,
|
||||
Self: Add<Self, Output = Self>,
|
||||
Self: Sub<Self, Output = Self>,
|
||||
|
@ -564,35 +577,36 @@ pub trait Angle where
|
|||
Self::normalize((self - other) * half + self)
|
||||
}
|
||||
|
||||
/// The additive identity.
|
||||
///
|
||||
/// Adding this to another angle has no affect.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
/// ```rust
|
||||
/// use cgmath::prelude::*;
|
||||
/// use cgmath::Deg;
|
||||
///
|
||||
/// let v = Deg::new(180.0);
|
||||
/// assert_eq!(v + Deg::zero(), v);
|
||||
/// ```
|
||||
fn zero() -> Self;
|
||||
|
||||
/// A full rotation.
|
||||
fn full_turn() -> Self;
|
||||
|
||||
/// Half of a full rotation.
|
||||
fn turn_div_2() -> Self;
|
||||
#[inline]
|
||||
fn turn_div_2() -> Self {
|
||||
let factor: Self::Unitless = cast(2).unwrap();
|
||||
Self::full_turn() / factor
|
||||
}
|
||||
|
||||
/// A third of a full rotation.
|
||||
fn turn_div_3() -> Self;
|
||||
#[inline]
|
||||
fn turn_div_3() -> Self {
|
||||
let factor: Self::Unitless = cast(3).unwrap();
|
||||
Self::full_turn() / factor
|
||||
}
|
||||
|
||||
/// A quarter of a full rotation.
|
||||
fn turn_div_4() -> Self;
|
||||
#[inline]
|
||||
fn turn_div_4() -> Self {
|
||||
let factor: Self::Unitless = cast(4).unwrap();
|
||||
Self::full_turn() / factor
|
||||
}
|
||||
|
||||
/// A sixth of a full rotation.
|
||||
fn turn_div_6() -> Self;
|
||||
#[inline]
|
||||
fn turn_div_6() -> Self {
|
||||
let factor: Self::Unitless = cast(6).unwrap();
|
||||
Self::full_turn() / factor
|
||||
}
|
||||
|
||||
/// Compute the sine of the angle, returning a unitless ratio.
|
||||
///
|
||||
|
|
|
@ -140,15 +140,22 @@ macro_rules! impl_vector {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: BaseNum> VectorSpace for $VectorN<S> {
|
||||
type Scalar = S;
|
||||
impl<S: BaseNum> Zero for $VectorN<S> {
|
||||
#[inline]
|
||||
fn zero() -> $VectorN<S> {
|
||||
$VectorN::from_value(S::zero())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn zero() -> Self {
|
||||
Self::from_value(Self::Scalar::zero())
|
||||
fn is_zero(&self) -> bool {
|
||||
*self == $VectorN::zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: BaseNum> VectorSpace for $VectorN<S> {
|
||||
type Scalar = S;
|
||||
}
|
||||
|
||||
impl<S: Neg<Output = S>> Neg for $VectorN<S> {
|
||||
type Output = $VectorN<S>;
|
||||
|
||||
|
|
Loading…
Reference in a new issue