Finished the Vector definition.
This complete what is needed for the definition of Vector2, Vector3, and Vector4. This required a trigonometry section, fleshing out the rest of the Number, ToNumber, and FromNumber section, correctly defining all the available function for the Real trait, and defining several constants.
This commit is contained in:
parent
e410e69e2f
commit
7ae702fd5c
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Sigils #
|
||||
A mathematics library.
|
||||
|
||||
The code in this library uses macros pretty heavily. As such,
|
||||
please check the trait's documentation for a function since the
|
||||
macro definition will not really be documented. This was not
|
||||
done to make documentation difficult, but to make coding the
|
||||
library easier and to make it easier to maintain.
|
61
src/bounded.rs
Normal file
61
src/bounded.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use std::{u8, u16, u32, u64, usize, i8, i16, i32, i64, isize, f32, f64};
|
||||
|
||||
|
||||
/// Primitive types that have upper and lower bounds.
|
||||
pub trait Bounded
|
||||
{
|
||||
// TODO: I would love for this to be associated consts, but
|
||||
// they are not currently working inside macros.
|
||||
// It causes rust's stack to explode.
|
||||
// Check this on later versions of rustc.
|
||||
//
|
||||
// Last version checked: rustc v1.3.0
|
||||
/// The minimum value for this type.
|
||||
//const MIN: Self;
|
||||
fn min_value() -> Self;
|
||||
|
||||
/// The maximum value for this type.
|
||||
//const MAX: Self;
|
||||
fn max_value() -> Self;
|
||||
}
|
||||
|
||||
|
||||
/// A macro for making implementation of
|
||||
/// the Bounded trait easier.
|
||||
macro_rules! bounded_trait_impl
|
||||
{
|
||||
($T: ty, $minVal: expr, $maxVal: expr) =>
|
||||
{
|
||||
impl Bounded for $T
|
||||
{
|
||||
//const MIN: $T = $minVal;
|
||||
fn min_value() -> $T
|
||||
{
|
||||
$minVal
|
||||
}
|
||||
|
||||
//const MAX: $T = $maxVal;
|
||||
fn max_value() -> $T
|
||||
{
|
||||
$maxVal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implement the Bounded for all the primitive types.
|
||||
bounded_trait_impl!(u8, u8::MIN, u8::MAX);
|
||||
bounded_trait_impl!(u16, u16::MIN, u16::MAX);
|
||||
bounded_trait_impl!(u32, u32::MIN, u32::MAX);
|
||||
bounded_trait_impl!(u64, u64::MIN, u64::MAX);
|
||||
bounded_trait_impl!(usize, usize::MIN, usize::MAX);
|
||||
|
||||
bounded_trait_impl!(i8, i8::MIN, i8::MAX);
|
||||
bounded_trait_impl!(i16, i16::MIN, i16::MAX);
|
||||
bounded_trait_impl!(i32, i32::MIN, i32::MAX);
|
||||
bounded_trait_impl!(i64, i64::MIN, i64::MAX);
|
||||
bounded_trait_impl!(isize, isize::MIN, isize::MAX);
|
||||
|
||||
bounded_trait_impl!(f32, f32::MIN, f32::MAX);
|
||||
bounded_trait_impl!(f64, f64::MIN, f64::MAX);
|
289
src/constants.rs
Normal file
289
src/constants.rs
Normal file
@ -0,0 +1,289 @@
|
||||
use std::{f32, f64};
|
||||
|
||||
|
||||
// Create the Constants trait so that we can use
|
||||
// associated constants to define Mathematical constants for
|
||||
// the f32 and f64 types.
|
||||
/// Defines Mathematical constants.
|
||||
pub trait Constants
|
||||
{
|
||||
/// The square root of 2.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::SQRT_2;
|
||||
/// let val64: f64 = Constants::SQRT_2;
|
||||
/// # assert_eq!(val32, std::f32::consts::SQRT_2);
|
||||
/// # assert_eq!(val64, std::f64::consts::SQRT_2);
|
||||
///```
|
||||
const SQRT_2: Self;
|
||||
|
||||
/// The square root of 3.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::SQRT_3;
|
||||
/// let val64: f64 = Constants::SQRT_3;
|
||||
/// # assert_eq!(val32, 1.73205080756887729352f32);
|
||||
/// # assert_eq!(val64, 1.73205080756887729352f64);
|
||||
///```
|
||||
const SQRT_3: Self;
|
||||
|
||||
/// The inverse of the square root of 2
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::INVERSE_SQRT_2;
|
||||
/// let val64: f64 = Constants::INVERSE_SQRT_2;
|
||||
/// # assert_eq!(val32, 1.0f32 / std::f32::consts::SQRT_2);
|
||||
/// # assert_eq!(val64, 1.0f64 / std::f64::consts::SQRT_2);
|
||||
///```
|
||||
const INVERSE_SQRT_2: Self;
|
||||
|
||||
/// The inverse of the square root of 3.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::INVERSE_SQRT_3;
|
||||
/// let val64: f64 = Constants::INVERSE_SQRT_3;
|
||||
/// # assert_eq!(val32, 1.0f32 / 1.73205080756887729352f32);
|
||||
/// # assert_eq!(val64, 1.0f64 / 1.73205080756887729352f64);
|
||||
///```
|
||||
const INVERSE_SQRT_3: Self;
|
||||
|
||||
/// The mathematical constant [E][1]. Also known as [Euler's number][1].
|
||||
/// [1]: https://en.wikipedia.org/wiki/E_(mathematical_constant)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::E;
|
||||
/// let val64: f64 = Constants::E;
|
||||
/// # assert_eq!(val32, std::f32::consts::E);
|
||||
/// # assert_eq!(val64, std::f64::consts::E);
|
||||
///```
|
||||
const E: Self;
|
||||
|
||||
/// The log base 2 of E.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::LOG2_E;
|
||||
/// let val64: f64 = Constants::LOG2_E;
|
||||
/// # assert_eq!(val32, std::f32::consts::LOG2_E);
|
||||
/// # assert_eq!(val64, std::f64::consts::LOG2_E);
|
||||
///```
|
||||
const LOG2_E: Self;
|
||||
|
||||
/// The log base 10 of E.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::LOG10_E;
|
||||
/// let val64: f64 = Constants::LOG10_E;
|
||||
/// # assert_eq!(val32, std::f32::consts::LOG10_E);
|
||||
/// # assert_eq!(val64, std::f64::consts::LOG10_E);
|
||||
///```
|
||||
const LOG10_E: Self;
|
||||
|
||||
/// The natural log(ln) of 2.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::LOGE_2;
|
||||
/// let val64: f64 = Constants::LOGE_2;
|
||||
/// # assert_eq!(val32, 2.0f32.ln());
|
||||
/// # assert_eq!(val64, 2.0f64.ln());
|
||||
///```
|
||||
const LOGE_2: Self;
|
||||
|
||||
/// The natural log(ln) of 10.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::LOGE_10;
|
||||
/// let val64: f64 = Constants::LOGE_10;
|
||||
/// # assert_eq!(val32, 10.0f32.ln());
|
||||
/// # assert_eq!(val64, 10.0f64.ln());
|
||||
///```
|
||||
const LOGE_10: Self;
|
||||
|
||||
/// Two times the value of PI.
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::TWO_PI;
|
||||
/// let val64: f64 = Constants::TWO_PI;
|
||||
/// # assert_eq!(val32, std::f32::consts::PI * 2.0f32);
|
||||
/// # assert_eq!(val64, std::f64::consts::PI * 2.0f64);
|
||||
///```
|
||||
const TWO_PI: Self;
|
||||
|
||||
/// [PI][1]. The ratio of a circles circumference to its diameter.
|
||||
/// [1]: https://en.wikipedia.org/wiki/Pi
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::PI;
|
||||
/// let val64: f64 = Constants::PI;
|
||||
/// # assert_eq!(val32, std::f32::consts::PI);
|
||||
/// # assert_eq!(val64, std::f64::consts::PI);
|
||||
///```
|
||||
const PI: Self;
|
||||
|
||||
/// One half of PI. (PI/2)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::HALF_PI;
|
||||
/// let val64: f64 = Constants::HALF_PI;
|
||||
/// # assert_eq!(val32, std::f32::consts::PI / 2.0f32);
|
||||
/// # assert_eq!(val64, std::f64::consts::PI / 2.0f64);
|
||||
///```
|
||||
const HALF_PI: Self;
|
||||
|
||||
/// One third of PI. (PI/3)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::THIRD_PI;
|
||||
/// let val64: f64 = Constants::THIRD_PI;
|
||||
/// # assert_eq!(val32, std::f32::consts::PI / 3.0f32);
|
||||
/// # assert_eq!(val64, std::f64::consts::PI / 3.0f64);
|
||||
///```
|
||||
const THIRD_PI: Self;
|
||||
|
||||
/// One forth of PI. (PI/4)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::QUARTER_PI;
|
||||
/// let val64: f64 = Constants::QUARTER_PI;
|
||||
/// # assert_eq!(val32, std::f32::consts::PI / 4.0f32);
|
||||
/// # assert_eq!(val64, std::f64::consts::PI / 4.0f64);
|
||||
///```
|
||||
const QUARTER_PI: Self;
|
||||
|
||||
/// One sixth of PI. (PI/6)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::SIXTH_PI;
|
||||
/// let val64: f64 = Constants::SIXTH_PI;
|
||||
/// # assert_eq!(val32, std::f32::consts::PI / 6.0f32);
|
||||
/// # assert_eq!(val64, std::f64::consts::PI / 6.0f64);
|
||||
///```
|
||||
const SIXTH_PI: Self;
|
||||
|
||||
/// One eighth of PI. (PI/8)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::EIGHTH_PI;
|
||||
/// let val64: f64 = Constants::EIGHTH_PI;
|
||||
/// # assert_eq!(val32, std::f32::consts::PI / 8.0f32);
|
||||
/// # assert_eq!(val64, std::f64::consts::PI / 8.0f64);
|
||||
///```
|
||||
const EIGHTH_PI: Self;
|
||||
|
||||
/// The inverse of PI. (1/PI)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::INVERSE_PI;
|
||||
/// let val64: f64 = Constants::INVERSE_PI;
|
||||
/// # assert_eq!(val32, 1.0f32 / std::f32::consts::PI);
|
||||
/// # assert_eq!(val64, 1.0f64 / std::f64::consts::PI);
|
||||
///```
|
||||
const INVERSE_PI: Self;
|
||||
|
||||
/// Two times the inverse of PI. (2/PI)
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::TWO_INVERSE_PI;
|
||||
/// let val64: f64 = Constants::TWO_INVERSE_PI;
|
||||
/// # assert_eq!(val32, 2.0f32 / std::f32::consts::PI);
|
||||
/// # assert_eq!(val64, 2.0f64 / std::f64::consts::PI);
|
||||
///```
|
||||
const TWO_INVERSE_PI: Self;
|
||||
|
||||
/// Two times the inverse of the square root of PI. (2/sqrt(PI))
|
||||
///
|
||||
///```
|
||||
/// use sigils::Constants;
|
||||
///
|
||||
/// let val32: f32 = Constants::TWO_INVERSE_SQRT_PI;
|
||||
/// let val64: f64 = Constants::TWO_INVERSE_SQRT_PI;
|
||||
/// # assert_eq!(val32, 2.0f32 * (std::f32::consts::PI).sqrt().recip());
|
||||
/// # assert_eq!(val64, 2.0f64 * (std::f64::consts::PI).sqrt().recip());
|
||||
///```
|
||||
const TWO_INVERSE_SQRT_PI: Self;
|
||||
}
|
||||
|
||||
|
||||
// Implement a macro to simplify defining these constants
|
||||
// for the two different types, f32 and f64.
|
||||
macro_rules! constants_trait_impl
|
||||
{
|
||||
($T: ty, $sqrt2: expr, $sqrt3: expr, $e: expr,
|
||||
$log2e: expr, $log10e: expr, $loge2: expr, $loge10: expr,
|
||||
$pi: expr, $sqrtPI: expr) =>
|
||||
{
|
||||
impl Constants for $T
|
||||
{
|
||||
const SQRT_2: $T = $sqrt2;
|
||||
const SQRT_3: $T = $sqrt3;
|
||||
const INVERSE_SQRT_2: $T = 1.0 / $sqrt2;
|
||||
const INVERSE_SQRT_3: $T = 1.0 / $sqrt3;
|
||||
|
||||
const E: $T = $e;
|
||||
|
||||
const LOG2_E: $T = $log2e;
|
||||
const LOG10_E: $T = $log10e;
|
||||
const LOGE_2: $T = $loge2;
|
||||
const LOGE_10: $T = $loge10;
|
||||
|
||||
const TWO_PI: $T = 2.0 * $pi;
|
||||
const PI: $T = $pi;
|
||||
const HALF_PI: $T = $pi / 2.0;
|
||||
const THIRD_PI: $T = $pi / 3.0;
|
||||
const QUARTER_PI: $T = $pi / 4.0;
|
||||
const SIXTH_PI: $T = $pi / 6.0;
|
||||
const EIGHTH_PI: $T = $pi / 8.0;
|
||||
const INVERSE_PI: $T = 1.0 / $pi;
|
||||
const TWO_INVERSE_PI: $T = 2.0 / $pi;
|
||||
const TWO_INVERSE_SQRT_PI: $T = 2.0 / $sqrtPI;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Implement the math Constants.
|
||||
constants_trait_impl!(f32, f32::consts::SQRT_2, 1.73205080756887729352f32,
|
||||
f32::consts::E, f32::consts::LOG2_E,
|
||||
f32::consts::LOG10_E, f32::consts::LN_2,
|
||||
f32::consts::LN_10, f32::consts::PI,
|
||||
1.7724538509055159f32);
|
||||
constants_trait_impl!(f64, f64::consts::SQRT_2, 1.73205080756887729352f64,
|
||||
f64::consts::E, f64::consts::LOG2_E,
|
||||
f64::consts::LOG10_E, f64::consts::LN_2,
|
||||
f64::consts::LN_10, f64::consts::PI,
|
||||
1.7724538509055159f64);
|
20
src/lib.rs
20
src/lib.rs
@ -1,16 +1,28 @@
|
||||
//! A mathematical library.
|
||||
//! License: Proprietary
|
||||
//!
|
||||
//!
|
||||
#![feature(zero_one)]
|
||||
#![feature(float_from_str_radix)]
|
||||
#![feature(float_extras)]
|
||||
#![feature(associated_consts)]
|
||||
|
||||
|
||||
mod bounded;
|
||||
mod number;
|
||||
mod whole;
|
||||
mod integer;
|
||||
mod real;
|
||||
mod constants;
|
||||
|
||||
pub mod trig;
|
||||
pub mod vector;
|
||||
pub mod matrix;
|
||||
pub mod quaternion;
|
||||
|
||||
|
||||
pub use self::vector::Vector;
|
||||
pub use self::vector::Vector2;
|
||||
pub use self::vector::Vector3;
|
||||
pub use self::vector::Vector4;
|
||||
pub use self::number::Number;
|
||||
pub use self::whole::Whole;
|
||||
pub use self::integer::Integer;
|
||||
pub use self::real::Real;
|
||||
pub use self::constants::Constants;
|
||||
|
1
src/matrix.rs
Normal file
1
src/matrix.rs
Normal file
@ -0,0 +1 @@
|
||||
//! This module defines the 2x2, 3x3, and 4x4 Matrix structures.
|
787
src/number.rs
787
src/number.rs
@ -1,7 +1,10 @@
|
||||
use std::cmp::PartialEq;
|
||||
use std::mem::size_of;
|
||||
use std::num::{Zero, One};
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
||||
|
||||
use super::bounded::Bounded;
|
||||
|
||||
|
||||
/// A trait that defines what is required to be considered
|
||||
/// a number.
|
||||
@ -12,34 +15,751 @@ pub trait Number : Zero + One + Add<Output=Self> + Sub<Output=Self> +
|
||||
type StrRadixError;
|
||||
|
||||
/// Create a number from a given string and base radix.
|
||||
///
|
||||
///```
|
||||
/// // Parse the hex value "FF" into an i32.
|
||||
/// // Hex values have a radix (base) of 16.
|
||||
/// use sigils::Number;
|
||||
///
|
||||
/// let x: i32 = Number::from_str_radix("FF", 16u32).unwrap();
|
||||
/// # assert_eq!(x, 255i32);
|
||||
///```
|
||||
fn from_str_radix(src: &str, radix: u32) ->
|
||||
Result<Self, Self::StrRadixError>;
|
||||
}
|
||||
|
||||
|
||||
// Create some macros to ease typing and reading.
|
||||
/// A macro to make implementing the trait easier for all the
|
||||
/// base integer types in rust.
|
||||
macro_rules! int_trait_impl
|
||||
/// A trait that defines converting something to a Number.
|
||||
pub trait ToNumber
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl Number for $varType
|
||||
{
|
||||
type StrRadixError = ::std::num::ParseIntError;
|
||||
/// Convert this to an u8.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
fn from_str_radix(src: &str, radix: u32) ->
|
||||
Result<Self, ::std::num::ParseIntError>
|
||||
{
|
||||
<$varType>::from_str_radix(src, radix)
|
||||
}
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_u8()
|
||||
}
|
||||
)*)
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an u16.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_u16()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an u32.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_u32()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an u64.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_u64(&self) -> Option<u64>;
|
||||
|
||||
/// Convert this to an usize.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
let option: Option<u64>;
|
||||
|
||||
option = self.to_u64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_usize()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Convert this to an i8.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_i8()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an i16.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_i16()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an i32.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_i32()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an i64.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_i64(&self) -> Option<i64>;
|
||||
|
||||
/// Convert this to an isize.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_isize()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Convert this to an f32.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
let option: Option<f64>;
|
||||
|
||||
option = self.to_f64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_f32()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this to an f64.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
let option: Option<i64>;
|
||||
|
||||
option = self.to_i64();
|
||||
match option
|
||||
{
|
||||
Some(val) =>
|
||||
{
|
||||
val.to_f64()
|
||||
}
|
||||
|
||||
None =>
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro to make implementing the trait easier for all the
|
||||
/// A trait that defines convertung a Number to something else.
|
||||
pub trait FromNumber : Sized
|
||||
{
|
||||
/// Convert an i8 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i8(number: i8) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
/// Convert an i16 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i16(number: i16) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
/// Convert an i32 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i32(number: i32) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
/// Convert an i64 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_i64(number: i64) -> Option<Self>;
|
||||
|
||||
/// Convert an isize to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_isize(number: isize) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
|
||||
|
||||
/// Convert an u8 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u8(number: u8) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
/// Convert an u16 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u16(number: u16) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
/// Convert an u32 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u32(number: u32) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
/// Convert an u64 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_u64(number: u64) -> Option<Self>;
|
||||
|
||||
/// Convert an usize to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_usize(number: usize) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_u64(number as u64)
|
||||
}
|
||||
|
||||
|
||||
/// Convert an f32 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_f32(number: f32) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_f64(number as f64)
|
||||
}
|
||||
|
||||
/// Convert an f64 to an optional value of this type.
|
||||
/// None is returned if the conversion is not possible.
|
||||
fn from_f64(number: f64) -> Option<Self>
|
||||
{
|
||||
FromNumber::from_i64(number as i64)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create some macros to ease typing and reading.
|
||||
macro_rules! convert_int_to_int
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
{
|
||||
let num: i64;
|
||||
let min_value: $dstType;
|
||||
let max_value: $dstType;
|
||||
|
||||
num = $val as i64;
|
||||
min_value = Bounded::min_value();
|
||||
max_value = Bounded::max_value();
|
||||
|
||||
if (min_value as i64) <= num && num <= (max_value as i64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_int_to_uint
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
{
|
||||
let zero: $srcType;
|
||||
let max_value: $dstType;
|
||||
|
||||
zero = Zero::zero();
|
||||
max_value = Bounded::max_value();
|
||||
|
||||
if zero <= $val && ($val as u64) <= (max_value as u64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_uint_to_int
|
||||
{
|
||||
($dstType: ty, $val: expr) =>
|
||||
{
|
||||
{
|
||||
let max_value: $dstType;
|
||||
|
||||
max_value = Bounded::max_value();
|
||||
if ($val as u64) <= (max_value as u64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_uint_to_uint
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
if size_of::<$srcType>() <= size_of::<$dstType>()
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
let zero: $srcType;
|
||||
let max_value: $dstType;
|
||||
|
||||
zero = Zero::zero();
|
||||
max_value = Bounded::max_value();
|
||||
|
||||
if zero <= $val && ($val as u64) <= (max_value as u64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! convert_float_to_float
|
||||
{
|
||||
($srcType: ty, $dstType: ty, $val: expr) =>
|
||||
{
|
||||
if size_of::<$srcType>() <= size_of::<$dstType>()
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
let num: f64;
|
||||
let min_value: $srcType;
|
||||
let max_value: $srcType;
|
||||
|
||||
num = $val as f64;
|
||||
min_value = Bounded::min_value();
|
||||
max_value = Bounded::max_value();
|
||||
|
||||
if (min_value as f64) <= num && num <= (max_value as f64)
|
||||
{
|
||||
Some($val as $dstType)
|
||||
}
|
||||
else
|
||||
{
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! int_to_number_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl $traitName for $varType
|
||||
{
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
{
|
||||
convert_int_to_uint!($varType, u8, *self)
|
||||
}
|
||||
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
convert_int_to_uint!($varType, u16, *self)
|
||||
}
|
||||
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
convert_int_to_uint!($varType, u32, *self)
|
||||
}
|
||||
|
||||
fn to_u64(&self) -> Option<u64>
|
||||
{
|
||||
convert_int_to_uint!($varType, u64, *self)
|
||||
}
|
||||
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
convert_int_to_uint!($varType, usize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
convert_int_to_int!($varType, i8, *self)
|
||||
}
|
||||
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
convert_int_to_int!($varType, i16, *self)
|
||||
}
|
||||
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
convert_int_to_int!($varType, i32, *self)
|
||||
}
|
||||
|
||||
fn to_i64(&self) -> Option<i64>
|
||||
{
|
||||
convert_int_to_int!($varType, i64, *self)
|
||||
}
|
||||
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
convert_int_to_int!($varType, isize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
Some(*self as f32)
|
||||
}
|
||||
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
Some(*self as f64)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! uint_to_number_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl $traitName for $varType
|
||||
{
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u8, *self)
|
||||
}
|
||||
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u16, *self)
|
||||
}
|
||||
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u32, *self)
|
||||
}
|
||||
|
||||
fn to_u64(&self) -> Option<u64>
|
||||
{
|
||||
convert_uint_to_uint!($varType, u64, *self)
|
||||
}
|
||||
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
convert_uint_to_uint!($varType, usize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
convert_uint_to_int!(i8, *self)
|
||||
}
|
||||
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
convert_uint_to_int!(i16, *self)
|
||||
}
|
||||
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
convert_uint_to_int!(i32, *self)
|
||||
}
|
||||
|
||||
fn to_i64(&self) -> Option<i64>
|
||||
{
|
||||
convert_uint_to_int!(i64, *self)
|
||||
}
|
||||
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
convert_uint_to_int!(isize, *self)
|
||||
}
|
||||
|
||||
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
Some(*self as f32)
|
||||
}
|
||||
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
Some(*self as f64)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! float_to_number_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl $traitName for $varType
|
||||
{
|
||||
fn to_u8(&self) -> Option<u8>
|
||||
{
|
||||
Some(*self as u8)
|
||||
}
|
||||
|
||||
fn to_u16(&self) -> Option<u16>
|
||||
{
|
||||
Some(*self as u16)
|
||||
}
|
||||
|
||||
fn to_u32(&self) -> Option<u32>
|
||||
{
|
||||
Some(*self as u32)
|
||||
}
|
||||
|
||||
fn to_u64(&self) -> Option<u64>
|
||||
{
|
||||
Some(*self as u64)
|
||||
}
|
||||
|
||||
fn to_usize(&self) -> Option<usize>
|
||||
{
|
||||
Some(*self as usize)
|
||||
}
|
||||
|
||||
|
||||
fn to_i8(&self) -> Option<i8>
|
||||
{
|
||||
Some(*self as i8)
|
||||
}
|
||||
|
||||
fn to_i16(&self) -> Option<i16>
|
||||
{
|
||||
Some(*self as i16)
|
||||
}
|
||||
|
||||
fn to_i32(&self) -> Option<i32>
|
||||
{
|
||||
Some(*self as i32)
|
||||
}
|
||||
|
||||
fn to_i64(&self) -> Option<i64>
|
||||
{
|
||||
Some(*self as i64)
|
||||
}
|
||||
|
||||
fn to_isize(&self) -> Option<isize>
|
||||
{
|
||||
Some(*self as isize)
|
||||
}
|
||||
|
||||
|
||||
fn to_f32(&self) -> Option<f32>
|
||||
{
|
||||
convert_float_to_float!($varType, f32, *self)
|
||||
}
|
||||
|
||||
fn to_f64(&self) -> Option<f64>
|
||||
{
|
||||
convert_float_to_float!($varType, f64, *self)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
macro_rules! from_number_impl
|
||||
{
|
||||
($varType: ty, $toTypeFunc: ident) =>
|
||||
{
|
||||
impl FromNumber for $varType
|
||||
{
|
||||
fn from_u8(number: u8) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_u16(number: u16) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_u32(number: u32) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_u64(number: u64) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
|
||||
fn from_i8(number: i8) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_i16(number: i16) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_i32(number: i32) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_i64(number: i64) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
|
||||
fn from_f32(number: f32) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
|
||||
fn from_f64(number: f64) -> Option<$varType>
|
||||
{
|
||||
number.$toTypeFunc()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro to make implementing the Number trait easier for all the
|
||||
/// base integer types in rust.
|
||||
macro_rules! int_number_trait_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
impl $traitName for $varType
|
||||
{
|
||||
type StrRadixError = ::std::num::ParseIntError;
|
||||
|
||||
fn from_str_radix(src: &str, radix: u32) ->
|
||||
Result<Self, ::std::num::ParseIntError>
|
||||
{
|
||||
<$varType>::from_str_radix(src, radix)
|
||||
}
|
||||
}
|
||||
)*)
|
||||
}
|
||||
|
||||
/// A macro to make implementing the Number trait easier for all the
|
||||
/// base float types in rust.
|
||||
macro_rules! float_trait_impl
|
||||
macro_rules! float_number_trait_impl
|
||||
{
|
||||
($traitName: ident for $($varType: ty)*) =>
|
||||
($(
|
||||
@ -57,7 +777,30 @@ macro_rules! float_trait_impl
|
||||
}
|
||||
|
||||
|
||||
// Implement the trait for the types that are Numbers.
|
||||
int_trait_impl!(Number for u8 u16 u32 u64 usize);
|
||||
int_trait_impl!(Number for i8 i16 i32 i64 isize);
|
||||
float_trait_impl!(Number for f32 f64);
|
||||
// Implement the Number trait for the types that are Numbers.
|
||||
int_number_trait_impl!(Number for u8 u16 u32 u64 usize);
|
||||
int_number_trait_impl!(Number for i8 i16 i32 i64 isize);
|
||||
float_number_trait_impl!(Number for f32 f64);
|
||||
|
||||
// Implement the ToNumber and FromNumber traits for
|
||||
// the types that are Numbers. The FromNumber trait needs
|
||||
// to be defined after ToNumber since FromNumber uses
|
||||
// ToNumber definitions.
|
||||
uint_to_number_impl!(ToNumber for u8 u16 u32 u64 usize);
|
||||
int_to_number_impl!(ToNumber for i8 i16 i32 i64 isize);
|
||||
float_to_number_impl!(ToNumber for f32 f64);
|
||||
|
||||
from_number_impl!(u8, to_u8);
|
||||
from_number_impl!(u16, to_u16);
|
||||
from_number_impl!(u32, to_u32);
|
||||
from_number_impl!(u64, to_u64);
|
||||
from_number_impl!(usize, to_usize);
|
||||
|
||||
from_number_impl!(i8, to_i8);
|
||||
from_number_impl!(i16, to_i16);
|
||||
from_number_impl!(i32, to_i32);
|
||||
from_number_impl!(i64, to_i64);
|
||||
from_number_impl!(isize, to_isize);
|
||||
|
||||
from_number_impl!(f32, to_f32);
|
||||
from_number_impl!(f64, to_f64);
|
||||
|
5
src/quaternion.rs
Normal file
5
src/quaternion.rs
Normal file
@ -0,0 +1,5 @@
|
||||
//! This module defines the [Quaternion][1] and
|
||||
//! [DualQuaternion][2] structures.
|
||||
//!
|
||||
//! [1]: https://en.wikipedia.org/wiki/Quaternion
|
||||
//! [2]: https://en.wikipedia.org/wiki/Dual_quaternion
|
1091
src/real.rs
1091
src/real.rs
File diff suppressed because it is too large
Load Diff
26
src/trig.rs
Normal file
26
src/trig.rs
Normal file
@ -0,0 +1,26 @@
|
||||
//use super::constants::Constants;
|
||||
use super::real::Real;
|
||||
|
||||
|
||||
/*
|
||||
pub struct Radians<T> where T: Real
|
||||
{
|
||||
pub value: T
|
||||
}
|
||||
|
||||
pub struct Degrees<T> where T: Real
|
||||
{
|
||||
pub value: T
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
pub fn acos<T>(x: T) -> T where T: Real
|
||||
{
|
||||
x.acos()
|
||||
}
|
||||
|
||||
pub fn atan2<T>(x: T, y: T) -> T where T: Real
|
||||
{
|
||||
x.atan2(y)
|
||||
}
|
623
src/vector.rs
623
src/vector.rs
@ -1,11 +1,18 @@
|
||||
//! This module defines 2, 3, and 4 component [Vector][1] structures.
|
||||
//!
|
||||
//! [1]: https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics)
|
||||
use std::num::{Zero, One};
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem, Neg};
|
||||
|
||||
use super::number::Number;
|
||||
use super::real::Real;
|
||||
use super::trig::{acos, atan2};
|
||||
|
||||
|
||||
/// A trait that defines the minimum set of
|
||||
/// functions a Vector must implement.
|
||||
/// functions a [Vector][1] must implement.
|
||||
///
|
||||
/// [1]: https://en.wikipedia.org/wiki/Vector_(mathematics_and_physics)
|
||||
pub trait Vector<T> : Clone where T: Number
|
||||
{
|
||||
// Creation functions.
|
||||
@ -23,26 +30,6 @@ pub trait Vector<T> : Clone where T: Number
|
||||
///```
|
||||
fn from_value(val: T) -> Self;
|
||||
|
||||
/// Create a zero Vector. All components will be set to zero.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector4<u8> where all
|
||||
/// // the components are 0.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector = Vector4::<u8>::zero();
|
||||
/// # assert_eq!(vector.x, 0u8);
|
||||
/// # assert_eq!(vector.y, 0u8);
|
||||
/// # assert_eq!(vector.z, 0u8);
|
||||
/// # assert_eq!(vector.w, 0u8);
|
||||
/// ```
|
||||
// TODO: Should Vectors implement the Zero trait
|
||||
// instead of defining a function for it?
|
||||
fn zero() -> Self
|
||||
{
|
||||
Self::from_value(T::zero())
|
||||
}
|
||||
|
||||
/// Create an identity Vector. All components will be set to one.
|
||||
///
|
||||
/// ```
|
||||
@ -54,78 +41,75 @@ pub trait Vector<T> : Clone where T: Number
|
||||
/// # assert_eq!(vector.x, 1i32);
|
||||
/// # assert_eq!(vector.y, 1i32);
|
||||
/// ```
|
||||
// TODO: Should Vectors implement the One trait
|
||||
// instead of defining an identity function?
|
||||
fn identity() -> Self
|
||||
{
|
||||
Self::from_value(T::one())
|
||||
}
|
||||
|
||||
|
||||
// Scalar operations that result in a new Vector.
|
||||
/// Add a scalar value to this Vector and return a new Vector.
|
||||
// Scalar operations that change this Vector.
|
||||
/// Add a scalar value to this Vector.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector2<i32> where all
|
||||
/// // the components are 1. Then add 1 to it.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector = Vector2::<i32>::identity();
|
||||
/// let vector_two = vector.add_scalar(1i32);
|
||||
/// # assert_eq!(vector_two.x, 2i32);
|
||||
/// # assert_eq!(vector_two.y, 2i32);
|
||||
/// let mut vector = Vector2::<i32>::identity();
|
||||
/// vector.add_scalar(1i32);
|
||||
/// # assert_eq!(vector.x, 2i32);
|
||||
/// # assert_eq!(vector.y, 2i32);
|
||||
/// ```
|
||||
fn add_scalar(&self, scalar: T) -> Self;
|
||||
fn add_scalar(&mut self, scalar: T);
|
||||
|
||||
/// Subtract a scalar value from this Vector and return a new Vector.
|
||||
/// Subtract a scalar value from this Vector.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector4<f64> where all
|
||||
/// // the components are 1. Then subtract 1 from it.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector = Vector4::<f64>::identity();
|
||||
/// let vector_two = vector.sub_scalar(1.0f64);
|
||||
/// # assert_eq!(vector_two.x, 0f64);
|
||||
/// # assert_eq!(vector_two.y, 0f64);
|
||||
/// # assert_eq!(vector_two.z, 0f64);
|
||||
/// # assert_eq!(vector_two.w, 0f64);
|
||||
/// let mut vector = Vector4::<f64>::identity();
|
||||
/// vector.sub_scalar(1.0f64);
|
||||
/// # assert_eq!(vector.x, 0f64);
|
||||
/// # assert_eq!(vector.y, 0f64);
|
||||
/// # assert_eq!(vector.z, 0f64);
|
||||
/// # assert_eq!(vector.w, 0f64);
|
||||
/// ```
|
||||
fn sub_scalar(&self, scalar: T) -> Self;
|
||||
fn sub_scalar(&mut self, scalar: T);
|
||||
|
||||
/// Multiply this Vector by a scalar value and return a new Vector.
|
||||
/// Multiply this Vector by a scalar value.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector4<f64> where all
|
||||
/// // the components are 5. Then multiply it by 5.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector = Vector4::<f32>::from_value(5f32);
|
||||
/// let vector_two = vector.mul_scalar(5f32);
|
||||
/// # assert_eq!(vector_two.x, 25f32);
|
||||
/// # assert_eq!(vector_two.y, 25f32);
|
||||
/// # assert_eq!(vector_two.z, 25f32);
|
||||
/// # assert_eq!(vector_two.w, 25f32);
|
||||
/// let mut vector = Vector4::<f32>::from_value(5f32);
|
||||
/// vector.mul_scalar(5f32);
|
||||
/// # assert_eq!(vector.x, 25f32);
|
||||
/// # assert_eq!(vector.y, 25f32);
|
||||
/// # assert_eq!(vector.z, 25f32);
|
||||
/// # assert_eq!(vector.w, 25f32);
|
||||
/// ```
|
||||
fn mul_scalar(&self, scalar: T) -> Self;
|
||||
fn mul_scalar(&mut self, scalar: T);
|
||||
|
||||
/// Divide this Vector by a scalar value and return a new Vector.
|
||||
/// Divide this Vector by a scalar value.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector3<u8> where all
|
||||
/// // the components are 25. Then divide it by 5.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector = Vector3::<u8>::from_value(25u8);
|
||||
/// let vector_two = vector.div_scalar(5u8);
|
||||
/// # assert_eq!(vector_two.x, 5u8);
|
||||
/// # assert_eq!(vector_two.y, 5u8);
|
||||
/// # assert_eq!(vector_two.z, 5u8);
|
||||
/// let mut vector = Vector3::<u8>::from_value(25u8);
|
||||
/// vector.div_scalar(5u8);
|
||||
/// # assert_eq!(vector.x, 5u8);
|
||||
/// # assert_eq!(vector.y, 5u8);
|
||||
/// # assert_eq!(vector.z, 5u8);
|
||||
/// ```
|
||||
fn div_scalar(&self, scalar: T) -> Self;
|
||||
fn div_scalar(&mut self, scalar: T);
|
||||
|
||||
/// Divide this Vector by a scalar value, take the remainder,
|
||||
/// and return a new Vector.
|
||||
/// Divide this Vector by a scalar value and store the remainder.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector3<isize> where all
|
||||
@ -133,79 +117,226 @@ pub trait Vector<T> : Clone where T: Number
|
||||
/// // and take the remainder.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector = Vector3::<isize>::from_value(25isize);
|
||||
/// let vector_two = vector.rem_scalar(7isize);
|
||||
/// # assert_eq!(vector_two.x, 4isize);
|
||||
/// # assert_eq!(vector_two.y, 4isize);
|
||||
/// # assert_eq!(vector_two.z, 4isize);
|
||||
/// let mut vector = Vector3::<isize>::from_value(25isize);
|
||||
/// vector.rem_scalar(7isize);
|
||||
/// # assert_eq!(vector.x, 4isize);
|
||||
/// # assert_eq!(vector.y, 4isize);
|
||||
/// # assert_eq!(vector.z, 4isize);
|
||||
/// ```
|
||||
fn rem_scalar(&self, scalar: T) -> Self;
|
||||
|
||||
|
||||
// Vector operations that result in a new Vector.
|
||||
/// Add a Vector to this Vector and return a new Vector.
|
||||
fn add_vector(&self, vector: &Self) -> Self;
|
||||
|
||||
/// Subtract a Vector from this Vector and return a new Vector.
|
||||
fn sub_vector(&self, vector: &Self) -> Self;
|
||||
|
||||
/// Multiply this Vector by a Vector and return a new Vector.
|
||||
fn mul_vector(&self, vector: &Self) -> Self;
|
||||
|
||||
/// Divide this Vector by a Vector and return a new Vector.
|
||||
fn div_vector(&self, vector: &Self) -> Self;
|
||||
|
||||
/// Divide this Vector by a Vector, take the remainder,
|
||||
/// and return a new Vector.
|
||||
fn rem_vector(&self, vector: &Self) -> Self;
|
||||
|
||||
|
||||
// Scalar operations that change this Vector.
|
||||
/// Add a scalar value to this Vector.
|
||||
fn add_scalar_self(&mut self, scalar: T);
|
||||
|
||||
/// Subtract a scalar value from this Vector.
|
||||
fn sub_scalar_self(&mut self, scalar: T);
|
||||
|
||||
/// Multiply this Vector by a scalar value.
|
||||
fn mul_scalar_self(&mut self, scalar: T);
|
||||
|
||||
/// Divide this Vector by a scalar value.
|
||||
fn div_scalar_self(&mut self, scalar: T);
|
||||
|
||||
/// Divide this Vector by a scalar value and take the remainder.
|
||||
fn rem_scalar_self(&mut self, scalar: T);
|
||||
fn rem_scalar(&mut self, scalar: T);
|
||||
|
||||
|
||||
// Vector operations that change this Vector.
|
||||
/// Add a Vector to this Vector.
|
||||
fn add_vector_self(&mut self, vector: &Self);
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector2<i32> where all
|
||||
/// // the components are 1. Then add
|
||||
/// // another Vector2<i32>, where all the
|
||||
/// // components are 1, to it.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let mut vector = Vector2::<i32>::identity();
|
||||
/// let vector_two = Vector2::<i32>::identity();
|
||||
/// vector.add_vector(&vector_two);
|
||||
/// # assert_eq!(vector.x, 2i32);
|
||||
/// # assert_eq!(vector.y, 2i32);
|
||||
/// ```
|
||||
fn add_vector(&mut self, vector: &Self);
|
||||
|
||||
/// Subtract a Vector from this Vector.
|
||||
fn sub_vector_self(&mut self, vector: &Self);
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector3<i64> where all
|
||||
/// // the components are 5. Then subtract
|
||||
/// // a Vector3<i64>, where all the
|
||||
/// // components are 2, from it.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let mut vector = Vector3::<i64>::from_value(5i64);
|
||||
/// let vector_two = Vector3::<i64>::from_value(2i64);
|
||||
/// vector.sub_vector(&vector_two);
|
||||
/// # assert_eq!(vector.x, 3i64);
|
||||
/// # assert_eq!(vector.y, 3i64);
|
||||
/// # assert_eq!(vector.z, 3i64);
|
||||
/// ```
|
||||
fn sub_vector(&mut self, vector: &Self);
|
||||
|
||||
/// Multiply this Vector by a Vector.
|
||||
fn mul_vector_self(&mut self, vector: &Self);
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector4<f32> where all
|
||||
/// // the components are 6.5. Then multiply
|
||||
/// // it by another Vector4<f32>, where all the
|
||||
/// // components are 4.0.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let mut vector = Vector4::<f32>::from_value(6.5f32);
|
||||
/// let vector_two = Vector4::<f32>::from_value(4.0f32);
|
||||
/// vector.mul_vector(&vector_two);
|
||||
/// # assert_eq!(vector.x, 26.0f32);
|
||||
/// # assert_eq!(vector.y, 26.0f32);
|
||||
/// # assert_eq!(vector.z, 26.0f32);
|
||||
/// # assert_eq!(vector.w, 26.0f32);
|
||||
/// ```
|
||||
fn mul_vector(&mut self, vector: &Self);
|
||||
|
||||
/// Divide this Vector by a Vector.
|
||||
fn div_vector_self(&mut self, vector: &Self);
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector2<f64> where all
|
||||
/// // the components are 19. Then
|
||||
/// // divide it by another Vector2<f64>,
|
||||
/// // where all the components are 2.0.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let mut vector = Vector2::<f64>::from_value(19.0f64);
|
||||
/// let vector_two = Vector2::<f64>::from_value(2.0f64);
|
||||
/// vector.div_vector(&vector_two);
|
||||
/// # assert_eq!(vector.x, 9.5f64);
|
||||
/// # assert_eq!(vector.y, 9.5f64);
|
||||
/// ```
|
||||
fn div_vector(&mut self, vector: &Self);
|
||||
|
||||
/// Divide this Vector by a Vector and take the remainder.
|
||||
fn rem_vector_self(&mut self, vector: &Self);
|
||||
/// Divide this Vector by a Vector and store the remainder.
|
||||
///
|
||||
/// ```
|
||||
/// // Create a new Vector3<usize> where all
|
||||
/// // the components are 22. Then
|
||||
/// // divide it by another Vector3<usize>,
|
||||
/// // where all the components are 6.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let mut vector = Vector3::<usize>::from_value(22usize);
|
||||
/// let vector_two = Vector3::<usize>::from_value(6usize);
|
||||
/// vector.rem_vector(&vector_two);
|
||||
/// # assert_eq!(vector.x, 4usize);
|
||||
/// # assert_eq!(vector.y, 4usize);
|
||||
/// # assert_eq!(vector.z, 4usize);
|
||||
/// ```
|
||||
fn rem_vector(&mut self, vector: &Self);
|
||||
|
||||
// TODO: Look at defining negation
|
||||
|
||||
// Basic Vector functions.
|
||||
/// Get the sum of all the components of the Vector.
|
||||
///
|
||||
///```
|
||||
/// // Create a new Vector4<f32> where all
|
||||
/// // the components are 5.125. Then get
|
||||
/// // the sum of the Vector's components.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector: Vector4<f32> = Vector4::<f32>::from_value(5.125f32);
|
||||
/// let sum: f32 = vector.get_sum();
|
||||
/// # assert_eq!(sum, 20.5f32);
|
||||
///```
|
||||
fn get_sum(&self) -> T;
|
||||
|
||||
/// Get the product of all the components of the Vector.
|
||||
///
|
||||
///```
|
||||
/// // Create a new Vector3<isize> where all
|
||||
/// // the components are 3. Then get
|
||||
/// // the product of the Vector's components.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector: Vector3<isize> = Vector3::<isize>::from_value(3isize);
|
||||
/// let sum: isize = vector.get_product();
|
||||
/// # assert_eq!(sum, 27isize);
|
||||
///```
|
||||
fn get_product(&self) -> T;
|
||||
|
||||
/// Get the dot product between this and another Vector.
|
||||
fn dot(&self, vector: &Self) -> T
|
||||
///
|
||||
///```
|
||||
/// // Create a two new Vector3<i64> where all
|
||||
/// // the components are 3. Then get the
|
||||
/// // dot product of the two Vectors.
|
||||
/// use sigils::vector::*;
|
||||
///
|
||||
/// let vector: Vector3<i64> = Vector3::<i64>::from_value(3i64);
|
||||
/// let vector_two: Vector3<i64> = Vector3::<i64>::from_value(3i64);
|
||||
/// let dotProduct: i64 = vector.dot(&vector_two);
|
||||
/// # assert_eq!(dotProduct, 27i64);
|
||||
///```
|
||||
fn dot(&self, vector: &Self) -> T;
|
||||
}
|
||||
|
||||
/// Defines the [EuclideanVector][1] trait.
|
||||
///
|
||||
/// [1]: https://en.wikipedia.org/wiki/Euclidean_vector
|
||||
pub trait EuclideanVector<T> : Vector<T> where T: Real
|
||||
{
|
||||
/// Get the length of the Vector.
|
||||
fn get_length(&self) -> T
|
||||
{
|
||||
self.mul_vector(vector).get_sum()
|
||||
self.dot(self).sqrt()
|
||||
}
|
||||
|
||||
/// Get the squared length of the Vector.
|
||||
fn get_length_squared(&self) -> T
|
||||
{
|
||||
self.dot(self)
|
||||
}
|
||||
|
||||
/// Normalizes the Vector by multplying all the
|
||||
/// components by 1/|V|.
|
||||
fn normalize(&self) -> Self
|
||||
{
|
||||
let mut new_vector: Self;
|
||||
|
||||
new_vector = self.clone();
|
||||
new_vector.mul_scalar(self.get_length().recip());
|
||||
new_vector
|
||||
}
|
||||
|
||||
/// Normalizes the Vector by multplying all the
|
||||
/// components by 1/|V|.
|
||||
fn normalize_self(&mut self)
|
||||
{
|
||||
let length: T;
|
||||
|
||||
length = self.get_length().recip();
|
||||
self.mul_scalar(length)
|
||||
}
|
||||
|
||||
/// Determines if this Vector is perpendicular to another Vector.
|
||||
fn is_perpendicular_to(&self, vector: &Self) -> bool
|
||||
{
|
||||
// TODO: Make this work with a fudge factor since floats
|
||||
// are tricky.
|
||||
self.dot(vector) == T::zero()
|
||||
}
|
||||
|
||||
/// Calculates the angle between this vector and
|
||||
/// another Vector, in radians.
|
||||
fn angle(&self, vector: &Self) -> T;
|
||||
|
||||
/// Linearly interpolate the length of this Vector
|
||||
/// towards the length of another Vector by a given amount.
|
||||
fn lerp(&self, vector: &Self, amount: T) -> Self
|
||||
{
|
||||
let mut temp: Self;
|
||||
let mut new_vector: Self;
|
||||
|
||||
temp = vector.clone();
|
||||
temp.sub_vector(&self);
|
||||
temp.mul_scalar(amount);
|
||||
|
||||
new_vector = self.clone();
|
||||
new_vector.add_vector(&temp);
|
||||
new_vector
|
||||
}
|
||||
|
||||
/// Linearly interpolate the length of this Vector
|
||||
/// towards the length of another Vector by a given amount.
|
||||
fn lerp_self(&mut self, vector: &Self, amount: T)
|
||||
{
|
||||
let mut temp: Self;
|
||||
|
||||
temp = vector.clone();
|
||||
temp.mul_scalar(amount);
|
||||
self.add_vector(&temp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,6 +370,16 @@ macro_rules! binary_operator_impl
|
||||
($traitName: ident :: $funcName: ident,
|
||||
$structName: ident {$($field: ident),+}) =>
|
||||
{
|
||||
impl<T> $traitName<T> for $structName<T> where T: Number
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
|
||||
fn $funcName(self, scalar: T) -> $structName<T>
|
||||
{
|
||||
$structName::new($(self.$field.$funcName(scalar)),+)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> $traitName<T> for &'a $structName<T> where T: Number
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
@ -249,6 +390,59 @@ macro_rules! binary_operator_impl
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> $traitName<&'a T> for $structName<T> where T: Number
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
|
||||
fn $funcName(self, scalar: &'a T) -> $structName<T>
|
||||
{
|
||||
$structName::new($(self.$field.$funcName(*scalar)),+)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, T> $traitName<&'b T> for &'a $structName<T> where T: Number
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
|
||||
fn $funcName(self, scalar: &'b T) -> $structName<T>
|
||||
{
|
||||
$structName::new($(self.$field.$funcName(*scalar)),+)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> $traitName<$structName<T>> for $structName<T>
|
||||
where T: Number
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
|
||||
fn $funcName(self, vector: $structName<T>) -> $structName<T>
|
||||
{
|
||||
$structName::new($(self.$field.$funcName(vector.$field)),+)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> $traitName<$structName<T>> for &'a $structName<T>
|
||||
where T: Number
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
|
||||
fn $funcName(self, vector: $structName<T>) -> $structName<T>
|
||||
{
|
||||
$structName::new($(self.$field.$funcName(vector.$field)),+)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, T> $traitName<&'a $structName<T>> for $structName<T>
|
||||
where T: Number
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
|
||||
fn $funcName(self, vector: &'a $structName<T>) -> $structName<T>
|
||||
{
|
||||
$structName::new($(self.$field.$funcName(vector.$field)),+)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, T> $traitName<&'a $structName<T>> for &'b $structName<T>
|
||||
where T: Number
|
||||
{
|
||||
@ -268,12 +462,17 @@ macro_rules! define_vector
|
||||
{
|
||||
($structName: ident <$T: ident> {$($field: ident),+}) =>
|
||||
{
|
||||
// Do not add a where clause here or implementing
|
||||
// generic traits were the generic is different
|
||||
// will not work properly.
|
||||
/// This structure was defined with the macro
|
||||
/// define_vector.
|
||||
///
|
||||
/// Please excuse the lack of comments.
|
||||
/// Please excuse the lack of comments and refer
|
||||
/// to the trait definitions for comments about
|
||||
/// the implementation.
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Hash)]
|
||||
pub struct $structName<T> where T: Number
|
||||
pub struct $structName<T>
|
||||
{
|
||||
$(pub $field: T),+
|
||||
}
|
||||
@ -286,6 +485,21 @@ macro_rules! define_vector
|
||||
}
|
||||
}
|
||||
|
||||
// Give this vector a negation function when the
|
||||
// type stored in it is negatable.
|
||||
impl<$T> $structName<$T> where T: Copy + Neg<Output = $T>
|
||||
{
|
||||
/// Negate this vector in-place (multiply by -1).
|
||||
///
|
||||
///```
|
||||
///
|
||||
///```
|
||||
pub fn negate(&mut self)
|
||||
{
|
||||
$(self.$field = -self.$field);+
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Vector<T> for $structName<T> where T: Number
|
||||
{
|
||||
fn from_value(val: T) -> $structName<T>
|
||||
@ -293,105 +507,53 @@ macro_rules! define_vector
|
||||
$structName {$($field: val),+}
|
||||
}
|
||||
|
||||
fn add_scalar(&self, scalar: T) -> $structName<T>
|
||||
{
|
||||
self + scalar
|
||||
}
|
||||
|
||||
fn sub_scalar(&self, scalar: T) -> $structName<T>
|
||||
{
|
||||
self - scalar
|
||||
}
|
||||
|
||||
fn mul_scalar(&self, scalar: T) -> $structName<T>
|
||||
{
|
||||
self * scalar
|
||||
}
|
||||
|
||||
fn div_scalar(&self, scalar: T) -> $structName<T>
|
||||
{
|
||||
self / scalar
|
||||
}
|
||||
|
||||
fn rem_scalar(&self, scalar: T) -> $structName<T>
|
||||
{
|
||||
self % scalar
|
||||
}
|
||||
|
||||
|
||||
fn add_vector(&self, vector: &$structName<T>) -> $structName<T>
|
||||
{
|
||||
self + vector
|
||||
}
|
||||
|
||||
fn sub_vector(&self, vector: &$structName<T>) -> $structName<T>
|
||||
{
|
||||
self - vector
|
||||
}
|
||||
|
||||
fn mul_vector(&self, vector: &$structName<T>) -> $structName<T>
|
||||
{
|
||||
self * vector
|
||||
}
|
||||
|
||||
fn div_vector(&self, vector: &$structName<T>) -> $structName<T>
|
||||
{
|
||||
self / vector
|
||||
}
|
||||
|
||||
fn rem_vector(&self, vector: &$structName<T>) -> $structName<T>
|
||||
{
|
||||
self % vector
|
||||
}
|
||||
|
||||
|
||||
fn add_scalar_self(&mut self, scalar: T)
|
||||
fn add_scalar(&mut self, scalar: T)
|
||||
{
|
||||
*self = &*self + scalar;
|
||||
}
|
||||
|
||||
fn sub_scalar_self(&mut self, scalar: T)
|
||||
fn sub_scalar(&mut self, scalar: T)
|
||||
{
|
||||
*self = &*self - scalar;
|
||||
}
|
||||
|
||||
fn mul_scalar_self(&mut self, scalar: T)
|
||||
fn mul_scalar(&mut self, scalar: T)
|
||||
{
|
||||
*self = &*self * scalar;
|
||||
}
|
||||
|
||||
fn div_scalar_self(&mut self, scalar: T)
|
||||
fn div_scalar(&mut self, scalar: T)
|
||||
{
|
||||
*self = &*self / scalar;
|
||||
}
|
||||
|
||||
fn rem_scalar_self(&mut self, scalar: T)
|
||||
fn rem_scalar(&mut self, scalar: T)
|
||||
{
|
||||
*self = &*self % scalar;
|
||||
}
|
||||
|
||||
|
||||
fn add_vector_self(&mut self, vector: &$structName<T>)
|
||||
fn add_vector(&mut self, vector: &$structName<T>)
|
||||
{
|
||||
*self = &*self + vector;
|
||||
}
|
||||
|
||||
fn sub_vector_self(&mut self, vector: &$structName<T>)
|
||||
fn sub_vector(&mut self, vector: &$structName<T>)
|
||||
{
|
||||
*self = &*self - vector;
|
||||
}
|
||||
|
||||
fn mul_vector_self(&mut self, vector: &$structName<T>)
|
||||
fn mul_vector(&mut self, vector: &$structName<T>)
|
||||
{
|
||||
*self = &*self * vector;
|
||||
}
|
||||
|
||||
fn div_vector_self(&mut self, vector: &$structName<T>)
|
||||
fn div_vector(&mut self, vector: &$structName<T>)
|
||||
{
|
||||
*self = &*self / vector;
|
||||
}
|
||||
|
||||
fn rem_vector_self(&mut self, vector: &$structName<T>)
|
||||
fn rem_vector(&mut self, vector: &$structName<T>)
|
||||
{
|
||||
*self = &*self % vector;
|
||||
}
|
||||
@ -406,8 +568,42 @@ macro_rules! define_vector
|
||||
{
|
||||
perform_method_on_components!(mul, {$(self.$field),+})
|
||||
}
|
||||
|
||||
fn dot(&self, vector: &$structName<T>) -> T
|
||||
{
|
||||
self.mul(vector).get_sum()
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the Zero and One traits for the Vector.
|
||||
impl<T> Zero for $structName<T> where T: Number
|
||||
{
|
||||
fn zero() -> $structName<T>
|
||||
{
|
||||
$structName::from_value(T::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> One for $structName<T> where T: Number
|
||||
{
|
||||
fn one() -> $structName<T>
|
||||
{
|
||||
$structName::identity()
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the negation operator for the Vector structure.
|
||||
impl<T> Neg for $structName<T> where T: Neg<Output = T>
|
||||
{
|
||||
type Output = $structName<T>;
|
||||
|
||||
fn neg(self) -> $structName<T>
|
||||
{
|
||||
$structName::<T> {$($field: -self.$field),+}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the binary operations for this Vector structure.
|
||||
binary_operator_impl!(Add::add, $structName {$($field),+});
|
||||
binary_operator_impl!(Sub::sub, $structName {$($field),+});
|
||||
binary_operator_impl!(Mul::mul, $structName {$($field),+});
|
||||
@ -439,10 +635,17 @@ impl<T> Vector2<T> where T: Number
|
||||
Vector2::new(T::zero(), T::one())
|
||||
}
|
||||
|
||||
/// Calculate the perpendicular dot product.
|
||||
pub fn perpendicular_dot(&self, vector: &Vector2<T>) -> T
|
||||
{
|
||||
(self.x * vector.y) - (self.y * vector.x)
|
||||
}
|
||||
|
||||
/// Adds a z component with the given value to the Vector.
|
||||
pub fn extend(&self, val: T) -> Vector3<T>
|
||||
{
|
||||
Vector3::new(self.x, self.y, val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Vector3<T> where T: Number
|
||||
@ -473,6 +676,39 @@ impl<T> Vector3<T> where T: Number
|
||||
(self.z * vector.x) - (self.x * vector.z),
|
||||
(self.x * vector.y) - (self.y * vector.x))
|
||||
}
|
||||
|
||||
/// Calculate the cross product between this and another Vector
|
||||
/// and store it in this Vector.
|
||||
/// The final result will be a Vector perpendicular to both
|
||||
/// of the input Vectors.
|
||||
pub fn cross_self(&mut self, vector: &Vector3<T>)
|
||||
{
|
||||
*self = self.cross(&vector);
|
||||
}
|
||||
|
||||
/// Adds a w component with the given value to the Vector.
|
||||
pub fn extend(&self, val: T) -> Vector4<T>
|
||||
{
|
||||
Vector4::new(self.x, self.y, self.z, val)
|
||||
}
|
||||
|
||||
/// Discards the z component of the Vector.
|
||||
pub fn truncate(&self) -> Vector2<T>
|
||||
{
|
||||
self.truncate_component(2)
|
||||
}
|
||||
|
||||
/// Discards the component at the given index from the Vector.
|
||||
pub fn truncate_component(&self, index: isize) -> Vector2<T>
|
||||
{
|
||||
match index
|
||||
{
|
||||
0 => Vector2::new(self.y, self.z),
|
||||
1 => Vector2::new(self.x, self.z),
|
||||
2 => Vector2::new(self.x, self.y),
|
||||
_ => panic!("Component index {:?} is out of range.", index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Vector4<T> where T: Number
|
||||
@ -500,4 +736,51 @@ impl<T> Vector4<T> where T: Number
|
||||
{
|
||||
Vector4::new(T::zero(), T::zero(), T::zero(), T::one())
|
||||
}
|
||||
|
||||
/// Discards the w component of the Vector.
|
||||
pub fn truncate(&self) -> Vector3<T>
|
||||
{
|
||||
self.truncate_component(3)
|
||||
}
|
||||
|
||||
/// Discards the component at the given index from the Vector.
|
||||
pub fn truncate_component(&self, index: isize) -> Vector3<T>
|
||||
{
|
||||
match index
|
||||
{
|
||||
0 => Vector3::new(self.y, self.z, self.w),
|
||||
1 => Vector3::new(self.x, self.z, self.w),
|
||||
2 => Vector3::new(self.x, self.y, self.w),
|
||||
3 => Vector3::new(self.x, self.y, self.z),
|
||||
_ => panic!("Component index {:?} is out of range.", index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Implement the angle specific portion of the EuclideanVector.
|
||||
impl<T> EuclideanVector<T> for Vector2<T> where T: Real
|
||||
{
|
||||
fn angle(&self, vector: &Vector2<T>) -> T
|
||||
{
|
||||
//unimplemented!();
|
||||
atan2(self.perpendicular_dot(vector), self.dot(vector))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EuclideanVector<T> for Vector3<T> where T: Real
|
||||
{
|
||||
fn angle(&self, vector: &Vector3<T>) -> T
|
||||
{
|
||||
//unimplemented!();
|
||||
atan2(self.cross(vector).get_length(), self.dot(vector))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EuclideanVector<T> for Vector4<T> where T: Real
|
||||
{
|
||||
fn angle(&self, vector: &Vector4<T>) -> T
|
||||
{
|
||||
//unimplemented!();
|
||||
acos(self.dot(vector) / (self.get_length() * vector.get_length()))
|
||||
}
|
||||
}
|
||||
|
97
tests/constants.rs
Normal file
97
tests/constants.rs
Normal file
@ -0,0 +1,97 @@
|
||||
extern crate sigils;
|
||||
|
||||
use std::{f32, f64};
|
||||
use sigils::Constants;
|
||||
|
||||
|
||||
#[test]
|
||||
fn constant_check_f32()
|
||||
{
|
||||
let val: f32 = Constants::SQRT_2;
|
||||
assert_eq!(val, f32::consts::SQRT_2);
|
||||
let val: f32 = Constants::SQRT_3;
|
||||
assert_eq!(val, 1.73205080756887729352f32);
|
||||
let val: f32 = Constants::INVERSE_SQRT_2;
|
||||
assert_eq!(val, 1.0f32 / f32::consts::SQRT_2);
|
||||
let val: f32 = Constants::INVERSE_SQRT_3;
|
||||
assert_eq!(val, 1.0f32 / 1.73205080756887729352f32);
|
||||
|
||||
let val: f32 = Constants::E;
|
||||
assert_eq!(val, f32::consts::E);
|
||||
|
||||
let val: f32 = Constants::LOG2_E;
|
||||
assert_eq!(val, f32::consts::LOG2_E);
|
||||
let val: f32 = Constants::LOG10_E;
|
||||
assert_eq!(val, f32::consts::LOG10_E);
|
||||
let val: f32 = Constants::LOGE_2;
|
||||
assert_eq!(val, 2f32.ln());
|
||||
let val: f32 = Constants::LOGE_10;
|
||||
assert_eq!(val, 10f32.ln());
|
||||
|
||||
let val: f32 = Constants::TWO_PI;
|
||||
assert_eq!(val, 2f32 * f32::consts::PI);
|
||||
let val: f32 = Constants::PI;
|
||||
assert_eq!(val, f32::consts::PI);
|
||||
let val: f32 = Constants::HALF_PI;
|
||||
assert_eq!(val, f32::consts::PI / 2f32);
|
||||
let val: f32 = Constants::THIRD_PI;
|
||||
assert_eq!(val, f32::consts::PI / 3f32);
|
||||
let val: f32 = Constants::QUARTER_PI;
|
||||
assert_eq!(val, f32::consts::PI / 4f32);
|
||||
let val: f32 = Constants::SIXTH_PI;
|
||||
assert_eq!(val, f32::consts::PI / 6f32);
|
||||
let val: f32 = Constants::EIGHTH_PI;
|
||||
assert_eq!(val, f32::consts::PI / 8f32);
|
||||
let val: f32 = Constants::INVERSE_PI;
|
||||
assert_eq!(val, 1.0f32 / f32::consts::PI);
|
||||
let val: f32 = Constants::TWO_INVERSE_PI;
|
||||
assert_eq!(val, 2.0f32 / f32::consts::PI);
|
||||
let val: f32 = Constants::TWO_INVERSE_SQRT_PI;
|
||||
assert_eq!(val, 2.0f32 / (f32::consts::PI).sqrt());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn constant_check_f64()
|
||||
{
|
||||
let val: f64 = Constants::SQRT_2;
|
||||
assert_eq!(val, f64::consts::SQRT_2);
|
||||
let val: f64 = Constants::SQRT_3;
|
||||
assert_eq!(val, 1.73205080756887729352f64);
|
||||
let val: f64 = Constants::INVERSE_SQRT_2;
|
||||
assert_eq!(val, 1.0f64 / f64::consts::SQRT_2);
|
||||
let val: f64 = Constants::INVERSE_SQRT_3;
|
||||
assert_eq!(val, 1.0f64 / 1.73205080756887729352f64);
|
||||
|
||||
let val: f64 = Constants::E;
|
||||
assert_eq!(val, f64::consts::E);
|
||||
|
||||
let val: f64 = Constants::LOG2_E;
|
||||
assert_eq!(val, f64::consts::LOG2_E);
|
||||
let val: f64 = Constants::LOG10_E;
|
||||
assert_eq!(val, f64::consts::LOG10_E);
|
||||
let val: f64 = Constants::LOGE_2;
|
||||
assert_eq!(val, 2f64.ln());
|
||||
let val: f64 = Constants::LOGE_10;
|
||||
assert_eq!(val, 10f64.ln());
|
||||
|
||||
let val: f64 = Constants::TWO_PI;
|
||||
assert_eq!(val, 2f64 * f64::consts::PI);
|
||||
let val: f64 = Constants::PI;
|
||||
assert_eq!(val, f64::consts::PI);
|
||||
let val: f64 = Constants::HALF_PI;
|
||||
assert_eq!(val, f64::consts::PI / 2f64);
|
||||
let val: f64 = Constants::THIRD_PI;
|
||||
assert_eq!(val, f64::consts::PI / 3f64);
|
||||
let val: f64 = Constants::QUARTER_PI;
|
||||
assert_eq!(val, f64::consts::PI / 4f64);
|
||||
let val: f64 = Constants::SIXTH_PI;
|
||||
assert_eq!(val, f64::consts::PI / 6f64);
|
||||
let val: f64 = Constants::EIGHTH_PI;
|
||||
assert_eq!(val, f64::consts::PI / 8f64);
|
||||
let val: f64 = Constants::INVERSE_PI;
|
||||
assert_eq!(val, 1.0f64 / f64::consts::PI);
|
||||
let val: f64 = Constants::TWO_INVERSE_PI;
|
||||
assert_eq!(val, 2.0f64 / f64::consts::PI);
|
||||
let val: f64 = Constants::TWO_INVERSE_SQRT_PI;
|
||||
assert_eq!(val, 2.0f64 / (f64::consts::PI).sqrt());
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
extern crate sigils;
|
||||
|
||||
|
||||
mod constants;
|
||||
mod vector;
|
||||
|
346
tests/vector.rs
346
tests/vector.rs
@ -1,5 +1,6 @@
|
||||
extern crate sigils;
|
||||
|
||||
use std::ops::{Add, Sub, Mul, Div, Rem};
|
||||
use sigils::vector::*;
|
||||
|
||||
|
||||
@ -10,3 +11,348 @@ fn vector_creation()
|
||||
|
||||
assert_eq!(v.x, 1.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_add()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
||||
let scalar: f32 = 4.0f32;
|
||||
|
||||
let v_three = v.add(&v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v.add(v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v + &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v + &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_sub()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(9.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(4.0f32);
|
||||
let scalar: f32 = 4.0f32;
|
||||
|
||||
let v_three = v.sub(&v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v.sub(v_two);
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - &v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - v_two;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - 4.0f32;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = &v - &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
|
||||
let v_three = v - &scalar;
|
||||
assert_eq!(v_three.x, 5.0f32);
|
||||
assert_eq!(v_three.y, 5.0f32);
|
||||
assert_eq!(v_three.z, 5.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_mul()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(3.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
||||
let scalar: f32 = 5.0f32;
|
||||
|
||||
let v_three = v.mul(&v_two);
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v.mul(v_two);
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * &v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * &v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * v_two;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * 5.0f32;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * 5.0f32;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = &v * &scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
|
||||
let v_three = v * &scalar;
|
||||
assert_eq!(v_three.x, 15.0f32);
|
||||
assert_eq!(v_three.y, 15.0f32);
|
||||
assert_eq!(v_three.z, 15.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_div()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(5.0f32);
|
||||
let scalar: f32 = 5.0f32;
|
||||
|
||||
let v_three = v.div(&v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v.div(v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / 5.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / 5.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v / &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v / &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vector_rem()
|
||||
{
|
||||
let v: Vector3<f32> = Vector3::<f32>::from_value(15.0f32);
|
||||
|
||||
let v_two: Vector3<f32> = Vector3::<f32>::from_value(6.0f32);
|
||||
let scalar: f32 = 6.0f32;
|
||||
|
||||
let v_three = v.rem(&v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v.rem(v_two);
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % &v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % v_two;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % 6.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % 6.0f32;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = &v % &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
|
||||
let v_three = v % &scalar;
|
||||
assert_eq!(v_three.x, 3.0f32);
|
||||
assert_eq!(v_three.y, 3.0f32);
|
||||
assert_eq!(v_three.z, 3.0f32);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user