Compare commits

...

8 Commits

Author SHA1 Message Date
6b7619da2f Added back the natrual numbers. 2026-02-26 13:15:56 -05:00
948ac5f297 Adjusted the natrual definition to now handle sub.
This neded a subtraction that would work on natural numbers where
subtraction isn't closed. This will now handle it and filter to make
sure the answer is 1 or higher.
2026-02-26 13:14:21 -05:00
fbef05fcd1 [#2] Cleaned up the base traits.
I have switched to using the `core::` calling convention instead of using
the `std::` by means of `extern crate core as std`. This makes it so
that the library is easier to reason.

The `Number` trait has been broken up now into `Number` and `Natural`.
This was done to make it so that the pure mathematical types were
separate from the Rust implementation types.

I went and added better comments, including examples.

The macros were tightened up so that the implementations took up less
space.

The FromNumber and ToNumber stuff will need to be reimplemented yet.
Some of it seemed redundant with From and TryFrom traits now. It will be
something to come back to and implement at the end.
2026-02-12 19:21:53 -05:00
b014dd959c [#2] Preference for the mod.rs style.
I like the directory with a mod.rs file. It is more ergonomic from the
command line for me.
2026-02-12 19:20:37 -05:00
7112987742 [#2] Removing empty files.
These files were empty. They may have been in the plan, but never got
implemented. They can be added back when they are actually implementing
something.
2026-02-12 19:18:48 -05:00
b8652f6784 [#2] Updating for the refresh.
I updated the version number and gave the library a better description.

Also, I removed the pack and bindings requirement. Rust-lang now has a
libm replacement library it seems, and Sigils will be using that going
foreward.
2026-02-12 09:40:19 -05:00
d5b4490eab [#2] Removing the examples and tests.
I am removing the examples and tests. A lot of this needs to be redone
anyways, but they were getting in the way of testing the new changes. If
these are needed later they can be pulled back from the repository.
2026-02-12 09:37:51 -05:00
a91bdbaff4 Adjusted the comments to be more accurate.
Before I headed into the refresh of this library I wanted to write and
adjust somethings comments I had noticed.
2026-02-11 09:59:21 -05:00
19 changed files with 299 additions and 1878 deletions

View File

@ -1,8 +1,8 @@
[package] [package]
name = "sigils" name = "sigils"
version = "0.1.0" version = "0.2.0"
edition = "2024" edition = "2024"
description = "A mathematics library." description = "High-performance no_std linear algebra for simulations and embedded flight systems."
keywords = ["sigils", "math"] keywords = ["sigils", "math"]
repository = "https://workshop.cybermages.tech/CyberMages/sigils" repository = "https://workshop.cybermages.tech/CyberMages/sigils"
authors = ["Jason Travis Smith <Myrddin@CyberMages.tech>"] authors = ["Jason Travis Smith <Myrddin@CyberMages.tech>"]
@ -10,5 +10,3 @@ readme = "README.md"
license = "Apache-2.0" license = "Apache-2.0"
[dependencies] [dependencies]
binding = { version = "0.1.0", registry = "cybermages" }
pact = { version = "0.1.0", registry = "cybermages" }

View File

@ -1,13 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
use sigils::quaternion::{Quaternion};
pub fn main()
{
let quat: Quaternion<f64>;
quat = Quaternion::<f64>::default();
println!("Quaternion: {}", quat);
}

View File

@ -1,45 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
use sigils::{Constants, Degree, Radian, Trig};
fn main()
{
let mut val: f64;
let mut degrees: Degree<f64>;
let mut radians: Radian<f64>;
val = Constants::QUARTER_PI;
val *= 6f64;
radians = Radian::new(val);
degrees = Trig::acos(Trig::cos(radians));
println!("{:?}", radians);
println!("{:?}", degrees);
println!("");
radians = Radian::new(Constants::QUARTER_PI);
radians = Trig::acos(Trig::cos(radians));
degrees = Degree::from(radians);
println!("{:?}", radians);
println!("{:?}", degrees);
println!("");
degrees = Degree::new(270.0f64);
radians = Trig::acos(Trig::cos(degrees));
println!("{:?}", degrees);
println!("{:?}", radians);
println!("");
degrees = Degree::new(90.0f64);
degrees = Trig::acos(Trig::cos(degrees));
radians = Radian::from(degrees);
println!("{:?}", degrees);
println!("{:?}", radians);
println!("");
}

View File

@ -1,29 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
use sigils::vector::{EuclideanVector, Vector2, Vector3, Vector4};
pub fn main()
{
let length: f32;
let vec2: Vector2<f64>;
let vec3: Vector3<f64>;
let vec4: Vector4<f64>;
let vector: Vector4<f32>;
vec2 = Vector2::default();
println!("Vector2: {}", vec2);
vec3 = Vector3::default();
println!("Vector3: {}", vec3);
vec4 = Vector4::default();
println!("Vector4: {}", vec4);
vector = Vector4::new(5.5f32, 5.5f32, 5.5f32, 5.5f32);
length = vector.get_length();
println!("Vector: {} -- Length: {}", vector, length);
assert_eq!(length, 11.0f32);
}

View File

@ -1,13 +1,38 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp. // Sealed with Magistamp.
/// Primitive types that have upper and lower bounds. /// `Bounded` provides the inclusive minimum and maximum range limits
/// for a numeric type.
///
/// Rust types have actual upper and lower representation limits that don't
/// follow the mathematical definitions. For example a Natural number goes
/// from one to infinity but a u8 can only really represent a number between
/// zero and two hundred and fifty five. This let's use set the minimum and
/// maximum values a Rust type can represent so we can use them in code easily.
pub trait Bounded pub trait Bounded
{ {
/// The minimum value for this type. /// The minimum value for this type.
///
/// # Examples
/// ```rust
/// use sigils::Bounded;
///
/// let min = <u8 as Bounded>::MIN;
///
/// assert_eq!(min, u8::MIN);
/// ```
const MIN: Self; const MIN: Self;
/// The maximum value for this type. /// The maximum value for this type.
///
/// # Examples
/// ```rust
/// use sigils::Bounded;
///
/// let max = <f64 as Bounded>::MAX;
///
/// assert_eq!(max, f64::MAX);
/// ```
const MAX: Self; const MAX: Self;
} }
@ -17,83 +42,20 @@ pub trait Bounded
/// the Bounded trait easier. /// the Bounded trait easier.
macro_rules! bounded_trait_impl macro_rules! bounded_trait_impl
{ {
($T: ty, $minVal: expr, $maxVal: expr) => ($($T:ty),*) =>
{ {
$(
impl Bounded for $T impl Bounded for $T
{ {
const MIN: $T = $minVal; const MIN: $T = <$T>::MIN;
const MAX: $T = <$T>::MAX;
const MAX: $T = $maxVal;
} }
)*
} }
} }
// Implement the Bounded for all the primitive types. // Implement the Bounded for all the primitive types.
bounded_trait_impl!(u8, 0u8, !0u8); bounded_trait_impl!(u8, u16, u32, u64, u128, usize);
bounded_trait_impl!(u16, 0u16, !0u16); bounded_trait_impl!(i8, i16, i32, i64, i128, isize);
bounded_trait_impl!(u32, 0u32, !0u32); bounded_trait_impl!(f32, f64);
bounded_trait_impl!(u64, 0u64, !0u64);
bounded_trait_impl!(usize, 0usize, !0usize);
bounded_trait_impl!(i8, (!0i8 ^ (!0u8 >> 1u8) as i8),
!(!0i8 ^ (!0u8 >> 1u8) as i8));
bounded_trait_impl!(i16, (!0i16 ^ (!0u16 >> 1u16) as i16),
!(!0i16 ^ (!0u16 >> 1u16) as i16));
bounded_trait_impl!(i32, (!0i32 ^ (!0u32 >> 1u32) as i32),
!(!0i32 ^ (!0u32 >> 1u32) as i32));
bounded_trait_impl!(i64, (!0i64 ^ (!0u64 >> 1u64) as i64),
!(!0i64 ^ (!0u64 >> 1u64) as i64));
bounded_trait_impl!(isize, (!0isize ^ (!0usize >> 1usize) as isize),
!(!0isize ^ (!0usize >> 1usize) as isize));
bounded_trait_impl!(f32, -3.40282347e+38f32, 3.40282347e+38f32);
bounded_trait_impl!(f64, -1.7976931348623157e+308f64,
1.7976931348623157e+308f64);
#[cfg(test)]
mod tests
{
macro_rules! bounds_test
{
($T: ident, $func_name: ident, $minVal: expr, $maxVal: expr) =>
{
#[test]
fn $func_name()
{
assert_eq!($T::MIN, $minVal);
assert_eq!($T::MAX, $maxVal);
}
}
}
bounds_test!(u8, min_max_u8, 0u8, !0u8);
bounds_test!(u16, min_max_u16, 0u16, !0u16);
bounds_test!(u32, min_max_u32, 0u32, !0u32);
bounds_test!(u64, min_max_u64, 0u64, !0u64);
bounds_test!(usize, min_max_usize, 0usize, !0usize);
bounds_test!(i8, min_max_i8,
-1i8 << (((::std::mem::size_of::<i8>() as i8)*8i8)-1i8),
!(-1i8 << (((::std::mem::size_of::<i8>() as i8)*8i8)-1i8)));
bounds_test!(i16, min_max_i16,
-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16),
!(-1i16 << (((::std::mem::size_of::<i16>() as i16)*8i16)-1i16)));
bounds_test!(i32, min_max_i32,
-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32),
!(-1i32 << (((::std::mem::size_of::<i32>() as i32)*8i32)-1i32)));
bounds_test!(i64, min_max_i64,
-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64),
!(-1i64 << (((::std::mem::size_of::<i64>() as i64)*8i64)-1i64)));
bounds_test!(isize, min_max_isize,
-1isize << (((::std::mem::size_of::<isize>() as isize)*8isize)-1isize),
!(-1isize << (((::std::mem::size_of::<isize>() as isize)*8isize)-1isize)));
bounds_test!(f32, min_max_f32,
-3.40282347e+38f32, 3.40282347e+38f32);
bounds_test!(f64, min_max_f64,
-1.7976931348623157e+308f64,
1.7976931348623157e+308f64);
}

View File

@ -1,23 +1,38 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp. // Sealed with Magistamp.
//! A mathematical library. //! # Sigils
//! License: Proprietary
//! //!
//! A high performance, 'no_std' mathematical library designed for use in
//! simulations and flight systems.
//! //!
//! Sigils uses Rust's type system to strictly define a mathematical hierarchy
//! to ensure type-safe operations.
#![no_std] #![no_std]
extern crate core as std;
#[macro_use]
mod macros;
mod bounded; mod bounded;
mod natural;
mod zero;
mod one;
mod number; mod number;
mod one;
mod zero;
pub use self::bounded::Bounded;
pub use self::natural::Natural;
pub use self::number::Number;
pub use self::one::One;
pub use self::zero::Zero;
//#[macro_use]
//mod macros;
/*
mod whole; mod whole;
mod integer; mod integer;
mod real; mod real;
@ -28,11 +43,9 @@ mod trig;
pub mod vector; pub mod vector;
pub mod matrix; pub mod matrix;
pub mod quaternion; pub mod quaternion;
*/
/*
pub use self::bounded::Bounded;
pub use self::zero::Zero;
pub use self::one::One; pub use self::one::One;
pub use self::number::{Number, FromNumber}; pub use self::number::{Number, FromNumber};
pub use self::whole::Whole; pub use self::whole::Whole;
@ -40,3 +53,4 @@ pub use self::integer::Integer;
pub use self::real::Real; pub use self::real::Real;
pub use self::constants::Constants; pub use self::constants::Constants;
pub use self::trig::{Degree, Radian, Trig}; pub use self::trig::{Degree, Radian, Trig};
*/

View File

@ -1,3 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.

82
src/natural.rs Normal file
View File

@ -0,0 +1,82 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
use core::ops::{Add, AddAssign, Mul, MulAssign};
use crate::number::Number;
use crate::one::One;
/// A Natural number is a counting number from one to infinity.
/// 1, 2, 3, 4, 5, 6, ...
///
/// Rust types that are in this category are:
/// u8, u16, u32, u64, u128, usize
pub trait Natural: Number + One +
Add<Output=Self> + AddAssign +
Mul<Output=Self> + MulAssign +
{
/// Attempts to subtract a number from itself.
///
/// Since subtraction isn't closed under this set (1 - 2 = -1) the trait
/// doesn't enforce that Sub and SubAssign are implemented. This function,
/// however, allows for subtraction and handles the case where the result is
/// no longer within the `Natural` numbers domain.
///
/// # Arguments
/// `rhs`: The number to subtract.
///
/// # Returns
/// `None` if the subtraction would fall below 1.
/// `Some` if their is a valid result.
///
/// # Examples
/// ```rust
/// use sigils::Natural;
///
/// let x = 3u8 as Natural;
///
/// assert_eq!(x.try_sub(2), Some(1));
/// assert_eq!(x.try_sub(7), None);
/// ```
fn try_sub(self, rhs: Self) -> Option<Self>;
/*
///
fn try_div(self, rhs: Self) -> Option<Self>;
///
fn try_rem(self, rhs: Self) -> Option<Self>;
/// Performs division and returns both the quotient and remainder.
#[inline]
fn try_div_rem(self, rhs: Self) -> Option<(Self, Self)>
{
Some((self.try_div(rhs)?, self.try_rem(rhs)?))
}
*/
}
/// A macro to make implementing the `Natural` trait easier for all the
/// base types in Rust.
macro_rules! natural_trait_impl
{
($($varType:ty),*) =>
{
$(
impl Natural for $varType
{
#[inline]
fn try_sub(self, rhs: Self) -> Option<Self>
{
self.checked_sub(rhs).filter(|x| *x >= Self::one())
}
}
)*
}
}
// Implement the Number trait for the types that are Numbers.
natural_trait_impl!(u8, u16, u32, u64, u128, usize);

View File

@ -1,42 +1,35 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp. // Sealed with Magistamp.
use std::cmp::{PartialEq, PartialOrd}; use core::cmp::{PartialEq, PartialOrd};
use std::fmt::{Debug, Display}; use core::fmt::{Debug, Display};
use std::mem::size_of;
use std::ops::{Add, Sub, Mul, Div, Rem};
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
use std::str::FromStr;
use crate::bounded::Bounded;
use crate::zero::Zero;
use crate::one::One;
/// A trait that defines what is required to be considered
/// a number. /// `Number` helps bridge the gap between the rust implementation and the pure
pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> + /// math definitions.
Mul<Output=Self> + Div<Output=Self> + Rem<Output=Self> + ///
AddAssign<Self> + SubAssign<Self> + MulAssign<Self> + /// `Number` has some basic Rust representation requirements.
DivAssign<Self> + RemAssign<Self> + PartialEq + PartialOrd + ///
Copy + Clone + Debug + Display /// [`Sized`]: A `Number` has a known size at compile time.
/// [`Copy`] & [`Clone`]: A `Number` should be passed by value, not reference.
/// [`PartialEq`] & [`PartialOrd`]: Two instances of `Number` should be able to be compared.
/// [`Debug`] & [`Display`]: Easier to read output.
pub trait Number: Sized + Copy + Clone +
PartialEq + PartialOrd +
Debug + Display
{ {
type StrRadixError;
/// The smallest number that can be stored in this type.
//const MIN: Self;
/// The largest number that can be stored in this type.
//const MAX: Self;
/// Returns the maximum of the two numbers. /// Returns the maximum of the two numbers.
/// ///
/// ``` /// # Arguments
/// use ::sigils::Number; /// * `other` - Another value, of the same type, to compare.
///
/// # Returns
/// The larger value of the two numbers.
///
/// # Examples
/// ```rust
/// use sigils::Number;
/// ///
/// let x: f64; /// let x: f64;
/// let y: f64; /// let y: f64;
@ -45,12 +38,23 @@ pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
/// y = 2.0f64; /// y = 2.0f64;
/// assert_eq!(x.maximum(y), y); /// assert_eq!(x.maximum(y), y);
/// ``` /// ```
fn maximum(self, other: Self) -> Self; #[inline]
fn maximum(self, other: Self) -> Self
{
if self >= other { self } else { other }
}
/// Returns the minimum of the two numbers. /// Returns the minimum of the two numbers.
/// ///
/// ``` /// # Arguments
/// use ::sigils::Number; /// * `other` - Another value, of the same type, to compare.
///
/// # Returns
/// The smaller value of the two numbers.
///
/// # Examples
/// ```rust
/// use sigils::Number;
/// ///
/// let x: i16; /// let x: i16;
/// let y: i16; /// let y: i16;
@ -59,883 +63,29 @@ pub trait Number: Zero + One + Add<Output=Self> + Sub<Output=Self> +
/// y = 55i16; /// y = 55i16;
/// assert_eq!(x.minimum(y), x); /// assert_eq!(x.minimum(y), x);
/// ``` /// ```
fn minimum(self, other: Self) -> Self; #[inline]
/// 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>;
}
/// A trait that defines converting something to a Number.
pub trait ToNumber
{
/// Convert this to an u8.
/// None is returned if the conversion is not possible.
fn to_u8(&self) -> Option<u8>
{
let option: Option<u64>;
option = self.to_u64();
match option
{
Some(val) =>
{
val.to_u8()
}
None =>
{
None
}
}
}
/// Convert this to a 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 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;
max_value = Bounded::MAX;
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;
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;
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;
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;
max_value = Bounded::MAX;
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, $min: expr, $max: expr) =>
{
impl $traitName for $varType
{
type StrRadixError = ::std::num::ParseIntError;
//const MIN: Self = $min;
//const MAX: Self = $max;
fn maximum(self, other: Self) -> Self
{
if self >= other
{
self
}
else
{
other
}
}
fn minimum(self, other: Self) -> Self fn minimum(self, other: Self) -> Self
{ {
if self <= other if self <= other { self } else { other }
{
self
}
else
{
other
}
}
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_number_trait_impl
/// A macro to make implementing the `Number` trait easier for all the
/// base types in Rust.
macro_rules! number_trait_impl
{ {
($traitName: ident for $varType: ty, $min: expr, $max: expr, ($($varType:ty),*) =>
$minFunc: ident, $maxFunc: ident) =>
{ {
impl $traitName for $varType $(
{ impl Number for $varType {}
type StrRadixError = ::std::num::ParseFloatError; )*
//const MIN: Self = $min;
//const MAX: Self = $max;
fn maximum(self, other: Self) -> Self
{
unsafe
{
::pact::math::$maxFunc(self, other) as Self
}
}
fn minimum(self, other: Self) -> Self
{
unsafe
{
::pact::math::$minFunc(self, other) as Self
}
}
fn from_str_radix(src: &str, radix: u32) ->
Result<Self, ::std::num::ParseFloatError>
{
// TODO: Currently this will panic on a non base 10 radix.
// This is because the std library deprecated the
// from_str_radix function. Until a function can be
// written this will use the from_str function and
// panic for non base 10 requests.
assert!(radix == 10);
<$varType>::from_str(src)
}
}
} }
} }
// Implement the Number trait for the types that are Numbers. // Implement the Number trait for the types that are Numbers.
int_number_trait_impl!(Number for u8, 0u8, 255u8); number_trait_impl!(u8, u16, u32, u64, u128, usize);
int_number_trait_impl!(Number for u16, 0u16, 65535u16); number_trait_impl!(i8, i16, i32, i64, i128, isize);
int_number_trait_impl!(Number for u32, 0u32, 4294967295u32); number_trait_impl!(f32, f64);
int_number_trait_impl!(Number for u64, 0u64, 18446744073709551615u64);
int_number_trait_impl!(Number for i8, -128i8, 127i8);
int_number_trait_impl!(Number for i16, -32768i16, 32767i16);
int_number_trait_impl!(Number for i32, -2147483648i32, 2147483647i32);
int_number_trait_impl!(Number for i64, -9223372036854775808i64,
9223372036854775807i64);
float_number_trait_impl!(Number for f32, -3.40282347e+38f32,
3.40282347e+38f32,
fminf, fmaxf);
float_number_trait_impl!(Number for f64, -1.7976931348623157e+308f64,
1.7976931348623157e+308f64,
fmin, fmax);
#[cfg(target_pointer_width = "16")]
int_number_trait_impl!(Number for usize, 0usize, 65535usize);
#[cfg(target_pointer_width = "32")]
int_number_trait_impl!(Number for usize, 0usize, 4294967295usize);
#[cfg(target_pointer_width = "64")]
int_number_trait_impl!(Number for usize, 0usize, 18446744073709551615usize);
#[cfg(target_pointer_width = "16")]
int_number_trait_impl!(Number for isize, -32768isize, 32767isize);
#[cfg(target_pointer_width = "32")]
int_number_trait_impl!(Number for isize, -2147483648isize, 2147483647isize);
#[cfg(target_pointer_width = "64")]
int_number_trait_impl!(Number for isize, -9223372036854775808isize,
9223372036854775807isize);
// 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);

View File

@ -1,10 +1,13 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp. // Sealed with Magistamp.
use std::ops::Mul; use core::ops::{Mul, MulAssign};
/// Defines a multiplicative identity element for `Self`.
pub trait One: Sized + Mul<Self, Output=Self>
/// Defines a multiplicative identity.
pub trait One: Sized + PartialEq +
Mul<Self, Output=Self> + MulAssign
{ {
/// Returns the multiplicative identity element of `Self`, `1`. /// Returns the multiplicative identity element of `Self`, `1`.
/// ///
@ -14,44 +17,54 @@ pub trait One: Sized + Mul<Self, Output=Self>
/// a * 1 = a ∀ a ∈ Self /// a * 1 = a ∀ a ∈ Self
/// 1 * a = a ∀ a ∈ Self /// 1 * a = a ∀ a ∈ Self
/// ``` /// ```
/// [Multiplicative Identity](https://en.wikipedia.org/wiki/1#In_mathematics)
/// ///
/// # Purity /// # Purity
/// ///
/// This function should return the same result at all times regardless of /// This function must be a pure mathematical constant. It should return
/// external mutable state, for example values stored in TLS or in /// the same result at all times regardless of external mutable state, for
/// `static mut`s. /// example values stored in Thread Local Storage(TLS) or in `static mut`s.
fn one() -> Self; fn one() -> Self;
/// Returns `true` if the value is the multiplicative identity.
///
///
/// # Examples
/// ```rust
/// use sigils::One;
///
/// let x = 1u32;
/// assert!(x.is_one());
///
/// let y = 5f64;
/// assert!(!y.is_one());
/// ```
#[inline]
fn is_one(&self) -> bool
{
*self == Self::one()
}
} }
macro_rules! one_impl macro_rules! one_impl
{ {
($varType: ty, $val: expr) => ($($varType: ty),*) =>
{ {
$(
impl One for $varType impl One for $varType
{ {
fn one() -> $varType #[inline]
{ fn one() -> Self
$val { 1 as $varType }
}
} }
)*
} }
} }
// Implement the One trait for the basic rust types.
one_impl!(u8, u16, u32, u64, u128, usize);
one_impl!(u8, 1u8); one_impl!(i8, i16, i32, i64, i128, isize);
one_impl!(u16, 1u16); one_impl!(f32, f64);
one_impl!(u32, 1u32);
one_impl!(u64, 1u64);
one_impl!(usize, 1usize);
one_impl!(i8, 1i8);
one_impl!(i16, 1i16);
one_impl!(i32, 1i32);
one_impl!(i64, 1i64);
one_impl!(isize, 1isize);
one_impl!(f32, 1.0f32);
one_impl!(f64, 1.0f64);

View File

@ -1,3 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.

View File

@ -1,3 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.

View File

@ -17,7 +17,7 @@ use crate::vector::{EuclideanVector, Vector3};
/// A Quaternion is a combination of a scalar and a vector /// A Quaternion is a combination of a scalar and a vector
/// of complex numbers. /// of imaginary units.
/// ///
/// [S, V] = [S, Xi + Yj + Zk] /// [S, V] = [S, Xi + Yj + Zk]
/// ///
@ -28,9 +28,9 @@ use crate::vector::{EuclideanVector, Vector3};
/// ///
/// | | | /// | | |
/// |:-------:|:-------:| /// |:-------:|:-------:|
/// | ij = 1 | ik = -1 | /// | ij = k | ji = -k |
/// | jk = 1 | kj = -1 | /// | jk = i | kj = -i |
/// | ki = 1 | ji = -1 | /// | ki = j | ik = -j |
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Quaternion<T> pub struct Quaternion<T>
{ {
@ -274,6 +274,11 @@ impl<T> Quaternion<T> where T: Trig
/// conjugate of this Quaternion. /// conjugate of this Quaternion.
pub fn invert(&self) -> Quaternion<T> pub fn invert(&self) -> Quaternion<T>
{ {
// This only works for unit quaternions and the normalize here is doing
// the heavy lifting of fixing my drift for my skeleton rotations.
//
// JTS: To reuse this code for other domains, this needs to become the
// conjugate divided by the magnitude squared.
self.conjugate().normalize() self.conjugate().normalize()
} }

View File

@ -1,3 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.

View File

@ -1,10 +1,13 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp. // Sealed with Magistamp.
use std::ops::Add; use core::ops::{Add, AddAssign};
/// Defines an additive identity element for `Self`.
pub trait Zero: Sized + Add<Self, Output=Self>
/// Defines an additive identity.
pub trait Zero: Sized + PartialEq +
Add<Self, Output=Self> + AddAssign
{ {
/// Returns the additive identity element of `Self`, `0`. /// Returns the additive identity element of `Self`, `0`.
/// ///
@ -14,44 +17,55 @@ pub trait Zero: Sized + Add<Self, Output=Self>
/// a + 0 = a ∀ a ∈ Self /// a + 0 = a ∀ a ∈ Self
/// 0 + a = a ∀ a ∈ Self /// 0 + a = a ∀ a ∈ Self
/// ``` /// ```
/// [Additive Identity](https://en.wikipedia.org/wiki/Additive_identity)
/// ///
/// # Purity /// # Purity
/// ///
/// This function should return the same result at all times regardless of /// This function must be a pure mathematical constant. It should return
/// external mutable state, for example values stored in TLS or in /// the same result at all times regardless of external mutable state, for
/// `static mut`s. /// example values stored in Thread Local Storage(TLS) or in `static mut`s.
fn zero() -> Self; fn zero() -> Self;
/// Returns `true` if the value is the additive identity.
///
/// # Examples
/// ```rust
/// use sigils::Zero;
///
/// let x = 0u32;
/// assert!(x.is_zero());
///
/// let y = 5u64;
/// assert!(!y.is_zero());
/// ```
#[inline]
fn is_zero(&self) -> bool
{
*self == Self::zero()
}
} }
/// A macro to make implementing the `Zero` trait easier for all the
/// base types in Rust.
macro_rules! zero_impl macro_rules! zero_impl
{ {
($varType: ty, $val: expr) => ($($varType: ty),*) =>
{ {
$(
impl Zero for $varType impl Zero for $varType
{ {
fn zero() -> $varType #[inline]
{ fn zero() -> Self
$val { 0 as $varType }
}
} }
)*
} }
} }
// Implement the Zero trait for the basic rust types.
zero_impl!(u8, u16, u32, u64, u128, usize);
zero_impl!(u8, 0u8); zero_impl!(i8, i16, i32, i64, i128, isize);
zero_impl!(u16, 0u16); zero_impl!(f32, f64);
zero_impl!(u32, 0u32);
zero_impl!(u64, 0u64);
zero_impl!(usize, 0usize);
zero_impl!(i8, 0i8);
zero_impl!(i16, 0i16);
zero_impl!(i32, 0i32);
zero_impl!(i64, 0i64);
zero_impl!(isize, 0isize);
zero_impl!(f32, 0.0f32);
zero_impl!(f64, 0.0f64);

View File

@ -1,98 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
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());
}

View File

@ -1,5 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
mod constants;
mod vector;

View File

@ -1,615 +0,0 @@
// SPDX-License-Identifier: Apache-2.0
// Sealed with Magistamp.
use std::ops::{Add, Sub, Mul, Div, Rem};
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
use sigils::vector::*;
#[test]
fn vector_creation()
{
let v: Vector3<f32> = Vector3::<f32>::from_value(1.0f32);
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);
}
#[test]
fn vector_add_assign()
{
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 mut v_three = v.clone();
v_three.add_assign(&v_two);
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three.add_assign(v_two);
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three += &v_two;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three += v_two;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three += 4.0f32;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three += scalar;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three += &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_assign()
{
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 mut v_three = v.clone();
v_three.sub_assign(&v_two);
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three.sub_assign(v_two);
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three -= &v_two;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three -= v_two;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three -= 4.0f32;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three -= scalar;
assert_eq!(v_three.x, 5.0f32);
assert_eq!(v_three.y, 5.0f32);
assert_eq!(v_three.z, 5.0f32);
let mut v_three = v.clone();
v_three -= &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_assign()
{
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 mut v_three = v.clone();
v_three.mul_assign(&v_two);
assert_eq!(v_three.x, 15.0f32);
assert_eq!(v_three.y, 15.0f32);
assert_eq!(v_three.z, 15.0f32);
let mut v_three = v.clone();
v_three.mul_assign(v_two);
assert_eq!(v_three.x, 15.0f32);
assert_eq!(v_three.y, 15.0f32);
assert_eq!(v_three.z, 15.0f32);
let mut v_three = v.clone();
v_three *= &v_two;
assert_eq!(v_three.x, 15.0f32);
assert_eq!(v_three.y, 15.0f32);
assert_eq!(v_three.z, 15.0f32);
let mut v_three = v.clone();
v_three *= v_two;
assert_eq!(v_three.x, 15.0f32);
assert_eq!(v_three.y, 15.0f32);
assert_eq!(v_three.z, 15.0f32);
let mut v_three = v.clone();
v_three *= 5.0f32;
assert_eq!(v_three.x, 15.0f32);
assert_eq!(v_three.y, 15.0f32);
assert_eq!(v_three.z, 15.0f32);
let mut v_three = v.clone();
v_three*= scalar;
assert_eq!(v_three.x, 15.0f32);
assert_eq!(v_three.y, 15.0f32);
assert_eq!(v_three.z, 15.0f32);
let mut v_three = v.clone();
v_three *= &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_assign()
{
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 mut v_three = v.clone();
v_three.div_assign(&v_two);
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three.div_assign(v_two);
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three /= &v_two;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three /= v_two;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three /= 5.0f32;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three /= scalar;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three /= &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_assign()
{
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 mut v_three = v.clone();
v_three.rem_assign(&v_two);
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three.rem_assign(v_two);
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three %= &v_two;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three %= v_two;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three %= 6.0f32;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three %= scalar;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
let mut v_three = v.clone();
v_three %= &scalar;
assert_eq!(v_three.x, 3.0f32);
assert_eq!(v_three.y, 3.0f32);
assert_eq!(v_three.z, 3.0f32);
}