|
|
@@ -0,0 +1,720 @@ |
|
|
|
#![allow(dead_code)] |
|
|
|
|
|
|
|
use std::convert::{AsMut, AsRef}; |
|
|
|
use std::fmt::{Debug, Formatter, Result as FmtResult}; |
|
|
|
use std::ops::{Add, Deref, DerefMut, Div, Mul, Sub}; |
|
|
|
|
|
|
|
macro_rules! define_vec { |
|
|
|
($Name:ident, $size:tt, $($T:ident => $i:tt => $f:ident),*) => { |
|
|
|
#[repr(C, packed)] |
|
|
|
pub struct $Name<T> { |
|
|
|
$(pub $f: T,)+ |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> $Name<T> { |
|
|
|
#[inline] |
|
|
|
pub fn new($($f: T,)+) -> Self { |
|
|
|
Self { $($f,)+ } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Default for $Name<T> |
|
|
|
where |
|
|
|
T: Default |
|
|
|
{ |
|
|
|
#[inline] |
|
|
|
fn default() -> Self { |
|
|
|
Self { |
|
|
|
$($f: T::default(),)+ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Debug for $Name<T> |
|
|
|
where |
|
|
|
T: Debug |
|
|
|
{ |
|
|
|
fn fmt(&self, fmt: &mut Formatter<'_>) -> FmtResult { |
|
|
|
fmt.debug_list().entries(self.as_ref().iter()).finish() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T, S> PartialEq<$Name<S>> for $Name<T> |
|
|
|
where |
|
|
|
S: PartialEq<T>, |
|
|
|
{ |
|
|
|
fn eq(&self, other: &$Name<S>) -> bool { |
|
|
|
unsafe { true $(&& other.$f.eq(&self.$f))+ } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Eq for $Name<T> |
|
|
|
where |
|
|
|
T: Eq |
|
|
|
{ } |
|
|
|
|
|
|
|
impl<T> Deref for $Name<T> { |
|
|
|
type Target = [T; $size]; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn deref(&self) -> &Self::Target { |
|
|
|
self.as_ref() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> DerefMut for $Name<T> { |
|
|
|
#[inline] |
|
|
|
fn deref_mut(&mut self) -> &mut Self::Target { |
|
|
|
self.as_mut() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> AsRef<[T; $size]> for $Name<T> { |
|
|
|
#[inline] |
|
|
|
fn as_ref(&self) -> &[T; $size] { |
|
|
|
unsafe { |
|
|
|
let raw: * const _ = self; |
|
|
|
let raw = raw as * const [T; $size]; |
|
|
|
|
|
|
|
&*raw |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> AsMut<[T; $size]> for $Name<T> { |
|
|
|
#[inline] |
|
|
|
fn as_mut(&mut self) -> &mut [T; $size] { |
|
|
|
unsafe { |
|
|
|
let raw: * mut _ = self; |
|
|
|
let raw = raw as * mut [T; $size]; |
|
|
|
|
|
|
|
&mut *raw |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Clone for $Name<T> |
|
|
|
where |
|
|
|
T: Clone |
|
|
|
{ |
|
|
|
#[inline] |
|
|
|
fn clone(&self) -> Self { |
|
|
|
unsafe { |
|
|
|
Self { |
|
|
|
$($f: self.$f.clone(),)+ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Copy for $Name<T> |
|
|
|
where |
|
|
|
T: Copy |
|
|
|
{ } |
|
|
|
|
|
|
|
impl<T> From<[T; $size]> for $Name<T> |
|
|
|
where |
|
|
|
T: Copy, |
|
|
|
{ |
|
|
|
#[inline] |
|
|
|
fn from(arr: [T; $size]) -> Self { |
|
|
|
Self { |
|
|
|
$($f: arr[$i],)+ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> From<($($T,)+)> for $Name<T> { |
|
|
|
#[inline] |
|
|
|
fn from(($($f,)+): ($($T,)+)) -> Self { |
|
|
|
Self { |
|
|
|
$($f,)+ |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
define_vec!(Vector2, 2, T => 0 => x, T => 1 => y); |
|
|
|
define_vec!(Vector3, 3, T => 0 => x, T => 1 => y, T => 2 => z); |
|
|
|
define_vec!(Vector4, 4, T => 0 => x, T => 1 => y, T => 2 => z, T => 3 => w); |
|
|
|
|
|
|
|
type Vector2f = Vector2<gl::GLfloat>; |
|
|
|
type Vector3f = Vector3<gl::GLfloat>; |
|
|
|
type Vector4f = Vector4<gl::GLfloat>; |
|
|
|
|
|
|
|
type Vector2d = Vector2<gl::GLdouble>; |
|
|
|
type Vector3d = Vector3<gl::GLdouble>; |
|
|
|
type Vector4d = Vector4<gl::GLdouble>; |
|
|
|
|
|
|
|
type Vector2i = Vector2<gl::GLint>; |
|
|
|
type Vector3i = Vector3<gl::GLint>; |
|
|
|
type Vector4i = Vector4<gl::GLint>; |
|
|
|
|
|
|
|
/* Vector2 */ |
|
|
|
|
|
|
|
impl<T> Vector2<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
#[inline] |
|
|
|
pub fn multiply(mut self, v: T) -> Self { |
|
|
|
self.x = self.x * v; |
|
|
|
self.y = self.y * v; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn length(&self) -> T { |
|
|
|
Element::sqrt(self.x * self.x + self.y * self.y) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn normalize(mut self) -> Self { |
|
|
|
let len = self.length(); |
|
|
|
|
|
|
|
self.x = self.x / len; |
|
|
|
self.y = self.y / len; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn scalar(&self, other: &Self) -> T { |
|
|
|
self.x * other.x + self.y * other.y |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn angle(&self, other: &Self) -> T::AsFloat { |
|
|
|
let s = self.scalar(other); |
|
|
|
let l1 = self.length(); |
|
|
|
let l2 = self.length(); |
|
|
|
|
|
|
|
Element::acos(s / (l1 + l2)) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn angle2(&self, other: &Self) -> T::AsFloat { |
|
|
|
T::atan2( |
|
|
|
other.x * self.y - other.y * self.x, |
|
|
|
other.x * self.x + other.y * self.y, |
|
|
|
) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Add for Vector2<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = Self; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn add(mut self, other: Self) -> Self::Output { |
|
|
|
self.x = self.x + other.x; |
|
|
|
self.y = self.y + other.y; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Sub for Vector2<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = Self; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn sub(mut self, other: Self) -> Self::Output { |
|
|
|
self.x = self.x - other.x; |
|
|
|
self.y = self.y - other.y; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Mul for Vector2<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = T; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn mul(self, rhs: Self) -> Self::Output { |
|
|
|
self.scalar(&rhs) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Vector3 */ |
|
|
|
|
|
|
|
impl<T> Vector3<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
#[inline] |
|
|
|
pub fn multiply(mut self, v: T) -> Self { |
|
|
|
self.x = self.x * v; |
|
|
|
self.y = self.y * v; |
|
|
|
self.z = self.z * v; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn length(&self) -> T { |
|
|
|
Element::sqrt(self.x * self.x + self.y * self.y + self.z * self.z) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn normalize(mut self) -> Self { |
|
|
|
let len = self.length(); |
|
|
|
|
|
|
|
self.x = self.x / len; |
|
|
|
self.y = self.y / len; |
|
|
|
self.z = self.z / len; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn scalar(&self, other: &Self) -> T { |
|
|
|
self.x * other.x + self.y * other.y + self.z * other.z |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn cross(&self, other: &Self) -> Self { |
|
|
|
Self { |
|
|
|
x: self.y * other.z - self.z * other.y, |
|
|
|
y: self.z * other.x - self.x * other.z, |
|
|
|
z: self.x * other.y - self.y * other.x, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn angle(&self, other: &Self) -> T::AsFloat { |
|
|
|
let s = self.scalar(other); |
|
|
|
let l1 = self.length(); |
|
|
|
let l2 = self.length(); |
|
|
|
|
|
|
|
Element::acos(s / (l1 + l2)) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Add for Vector3<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = Self; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn add(mut self, other: Self) -> Self::Output { |
|
|
|
self.x = self.x + other.x; |
|
|
|
self.y = self.y + other.y; |
|
|
|
self.z = self.z + other.z; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Sub for Vector3<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = Self; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn sub(mut self, other: Self) -> Self::Output { |
|
|
|
self.x = self.x - other.x; |
|
|
|
self.y = self.y - other.y; |
|
|
|
self.z = self.z - other.z; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Mul for Vector3<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = T; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn mul(self, rhs: Self) -> Self::Output { |
|
|
|
self.scalar(&rhs) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Vector4 */ |
|
|
|
|
|
|
|
impl<T> Vector4<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
#[inline] |
|
|
|
pub fn multiply(mut self, v: T) -> Self { |
|
|
|
self.x = self.x * v; |
|
|
|
self.y = self.y * v; |
|
|
|
self.z = self.z * v; |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn length(self) -> T { |
|
|
|
self.xyz().length() |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn normalize(mut self) -> Self { |
|
|
|
let len = self.length(); |
|
|
|
|
|
|
|
if unsafe { !Element::is_zero(&self.w) } { |
|
|
|
self.x = self.x / self.w; |
|
|
|
self.y = self.y / self.w; |
|
|
|
self.z = self.z / self.w; |
|
|
|
} else { |
|
|
|
self.x = Element::zero(); |
|
|
|
self.y = Element::zero(); |
|
|
|
self.z = Element::zero(); |
|
|
|
} |
|
|
|
|
|
|
|
self.x = self.x / len; |
|
|
|
self.y = self.y / len; |
|
|
|
self.z = self.z / len; |
|
|
|
self.w = Element::one(); |
|
|
|
|
|
|
|
self |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn scalar(&self, other: &Self) -> T { |
|
|
|
self.xyz().scalar(&other.xyz()) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn cross(&self, other: &Self) -> Self { |
|
|
|
(self.xyz().cross(&other.xyz()), Element::one()).into() |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn angle(&self, other: &Self) -> T::AsFloat { |
|
|
|
self.xyz().angle(&other.xyz()) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
pub fn xyz(self) -> Vector3<T> { |
|
|
|
if unsafe { Element::is_zero(&self.w) } { |
|
|
|
Vector3 { |
|
|
|
x: Element::zero(), |
|
|
|
y: Element::zero(), |
|
|
|
z: Element::zero(), |
|
|
|
} |
|
|
|
} else { |
|
|
|
Vector3 { |
|
|
|
x: self.x / self.w, |
|
|
|
y: self.y / self.w, |
|
|
|
z: self.z / self.w, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Add for Vector4<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = Self; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn add(self, other: Self) -> Self::Output { |
|
|
|
(self.xyz() + other.xyz(), T::one()).into() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Sub for Vector4<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = Self; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn sub(self, other: Self) -> Self::Output { |
|
|
|
(self.xyz() - other.xyz(), T::one()).into() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> Mul for Vector4<T> |
|
|
|
where |
|
|
|
T: Element, |
|
|
|
{ |
|
|
|
type Output = T; |
|
|
|
|
|
|
|
fn mul(self, rhs: Self) -> Self::Output { |
|
|
|
self.scalar(&rhs) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl<T> From<(Vector3<T>, T)> for Vector4<T> { |
|
|
|
fn from((vec3, w): (Vector3<T>, T)) -> Self { |
|
|
|
Self { |
|
|
|
x: vec3.x, |
|
|
|
y: vec3.y, |
|
|
|
z: vec3.z, |
|
|
|
w, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Element */ |
|
|
|
|
|
|
|
pub trait Element: |
|
|
|
Sized |
|
|
|
+ Add<Self, Output = Self> |
|
|
|
+ Sub<Self, Output = Self> |
|
|
|
+ Mul<Self, Output = Self> |
|
|
|
+ Div<Self, Output = Self> |
|
|
|
+ Copy |
|
|
|
{ |
|
|
|
type AsFloat: Element; |
|
|
|
|
|
|
|
fn one() -> Self; |
|
|
|
fn zero() -> Self; |
|
|
|
fn sqrt(self) -> Self; |
|
|
|
fn acos(self) -> Self::AsFloat; |
|
|
|
fn atan(self) -> Self::AsFloat; |
|
|
|
fn atan2(a: Self, b: Self) -> Self::AsFloat; |
|
|
|
fn is_zero(&self) -> bool; |
|
|
|
} |
|
|
|
|
|
|
|
impl Element for gl::GLfloat { |
|
|
|
type AsFloat = f32; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn one() -> Self { |
|
|
|
1.0 |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn zero() -> Self { |
|
|
|
0.0 |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn sqrt(self) -> Self { |
|
|
|
f32::sqrt(self) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn acos(self) -> Self::AsFloat { |
|
|
|
f32::acos(self) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn atan(self) -> Self::AsFloat { |
|
|
|
f32::atan(self) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn atan2(a: Self, b: Self) -> Self::AsFloat { |
|
|
|
f32::atan2(a, b) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn is_zero(&self) -> bool { |
|
|
|
PartialEq::<f32>::eq(self, &0.0) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl Element for gl::GLdouble { |
|
|
|
type AsFloat = f64; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn one() -> Self { |
|
|
|
1.0 |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn zero() -> Self { |
|
|
|
0.0 |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn sqrt(self) -> Self { |
|
|
|
f64::sqrt(self) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn acos(self) -> Self::AsFloat { |
|
|
|
f64::acos(self) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn atan(self) -> Self::AsFloat { |
|
|
|
f64::atan(self) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn atan2(a: Self, b: Self) -> Self::AsFloat { |
|
|
|
f64::atan2(a, b) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn is_zero(&self) -> bool { |
|
|
|
PartialEq::<f64>::eq(self, &0.0) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
impl Element for gl::GLint { |
|
|
|
type AsFloat = f32; |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn one() -> Self { |
|
|
|
1 |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn zero() -> Self { |
|
|
|
0 |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn sqrt(self) -> Self { |
|
|
|
f64::sqrt(self as f64) as i32 |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn acos(self) -> Self::AsFloat { |
|
|
|
f32::acos(self as f32) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn atan(self) -> Self::AsFloat { |
|
|
|
f32::atan(self as f32) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn atan2(a: Self, b: Self) -> Self::AsFloat { |
|
|
|
f32::atan2(a as f32, b as f32) |
|
|
|
} |
|
|
|
|
|
|
|
#[inline] |
|
|
|
fn is_zero(&self) -> bool { |
|
|
|
PartialEq::<i32>::eq(self, &0) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#[cfg(test)] |
|
|
|
mod tests { |
|
|
|
use super::*; |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn add() { |
|
|
|
let v1 = Vector2f::from((1.0, 0.0)); |
|
|
|
let v2 = Vector2f::from((0.0, 1.0)); |
|
|
|
let ex = Vector2f::from((1.0, 1.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1 + v2); |
|
|
|
|
|
|
|
let v1 = Vector3f::from((1.0, 0.0, 1.8)); |
|
|
|
let v2 = Vector3f::from((0.0, 2.0, 1.2)); |
|
|
|
let ex = Vector3f::from((1.0, 2.0, 3.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1 + v2); |
|
|
|
|
|
|
|
let v1 = Vector4f::from((1.0, 0.0, 1.8, 0.5)); |
|
|
|
let v2 = Vector4f::from((0.0, 2.0, 1.2, 1.0)); |
|
|
|
let ex = Vector4f::from((2.0, 2.0, 4.8, 1.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1 + v2); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn sub() { |
|
|
|
let v1 = Vector2f::from((1.0, 0.0)); |
|
|
|
let v2 = Vector2f::from((0.0, 1.0)); |
|
|
|
let ex = Vector2f::from((1.0, -1.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1 - v2); |
|
|
|
|
|
|
|
let v1 = Vector3d::from((1.0, 0.0, 1.75)); |
|
|
|
let v2 = Vector3d::from((0.0, 2.0, 1.0)); |
|
|
|
let ex = Vector3d::from((1.0, -2.0, 0.75)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1 - v2); |
|
|
|
|
|
|
|
let v1 = Vector4d::from((1.0, 0.0, 1.0, 0.5)); |
|
|
|
let v2 = Vector4d::from((0.0, 2.0, -2.0, 1.0)); |
|
|
|
let ex = Vector4d::from((2.0, -2.0, 4.0, 1.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1 - v2); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn multiply() { |
|
|
|
let v1 = Vector2f::from((1.0, 0.0)).multiply(2.0); |
|
|
|
let ex = Vector2f::from((2.0, 0.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1); |
|
|
|
|
|
|
|
let v1 = Vector3d::from((1.0, 0.0, 1.75)).multiply(2.0); |
|
|
|
let ex = Vector3d::from((2.0, 0.0, 3.5)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1); |
|
|
|
|
|
|
|
let v1 = Vector4d::from((1.0, 0.0, 0.5, 0.5)).multiply(3.0); |
|
|
|
let ex = Vector4d::from((3.0, 0.0, 1.5, 0.5)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn scalar() { |
|
|
|
let v1 = Vector2f::from((1.0, 0.0)); |
|
|
|
let v2 = Vector2f::from((0.0, 1.0)); |
|
|
|
|
|
|
|
assert_eq!(0.0, v1.scalar(&v2)); |
|
|
|
|
|
|
|
let v1 = Vector3f::from((1.0, 0.0, 0.0)); |
|
|
|
let v2 = Vector3f::from((0.0, 1.0, 0.0)); |
|
|
|
|
|
|
|
assert_eq!(0.0, v1.scalar(&v2)); |
|
|
|
|
|
|
|
let v1 = Vector4f::from((3.0, 0.0, 0.0, 1.0)); |
|
|
|
let v2 = Vector4f::from((0.0, 2.0, 0.0, 0.8)); |
|
|
|
|
|
|
|
assert_eq!(0.0, v1.scalar(&v2)); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn normalize() { |
|
|
|
let v1 = Vector2f::from((1.0, 0.0)).normalize(); |
|
|
|
let ex = Vector2f::from((1.0, 0.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1); |
|
|
|
|
|
|
|
let v1 = Vector3d::from((1.0, 0.0, 1.75)).normalize(); |
|
|
|
let ex = Vector3d::from((0.49613893835683387, 0.0, 0.8682431421244593)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1); |
|
|
|
|
|
|
|
let v1 = Vector4d::from((1.0, 0.0, 0.5, 0.5)).normalize(); |
|
|
|
let ex = Vector4d::from((0.8944271909999159, 0.0, 0.4472135954999579, 1.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1); |
|
|
|
} |
|
|
|
|
|
|
|
#[test] |
|
|
|
fn cross() { |
|
|
|
let v1 = Vector3d::from((1.0, 0.0, 0.0)); |
|
|
|
let v2 = Vector3d::from((0.0, 1.0, 0.0)); |
|
|
|
let ex = Vector3d::from((0.0, 0.0, 1.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1.cross(&v2)); |
|
|
|
|
|
|
|
let v1 = Vector4d::from((1.0, 0.0, 0.0, 0.5)); |
|
|
|
let v2 = Vector4d::from((0.0, 3.0, 0.0, 1.0)); |
|
|
|
let ex = Vector4d::from((0.0, 0.0, 6.0, 1.0)); |
|
|
|
|
|
|
|
assert_eq!(ex, v1.cross(&v2)); |
|
|
|
} |
|
|
|
} |