Overhaul library, rename to cgmath
Moved the old source code temporarily to src-old. This will be removed once the functionality has been transferred over into the new system. The new design is based on algebraic principles. Thanks goes to sebcrozet and his nalgebra library for providing the inspiration for the algebraic traits: https://github.com/sebcrozet/nalgebra
This commit is contained in:
parent
c429ed839d
commit
3673c4db6d
49 changed files with 1112 additions and 100 deletions
5
AUTHORS
5
AUTHORS
|
@ -11,3 +11,8 @@ Erick Tryzelaar
|
||||||
Luqman Aden
|
Luqman Aden
|
||||||
Maik Klein
|
Maik Klein
|
||||||
Mikko Perttunen
|
Mikko Perttunen
|
||||||
|
|
||||||
|
With thanks to:
|
||||||
|
|
||||||
|
sebcrozet and his nalgebra library for providing the inspiration for the
|
||||||
|
algebraic traits: https://github.com/sebcrozet/nalgebra
|
||||||
|
|
49
Makefile
49
Makefile
|
@ -1,49 +0,0 @@
|
||||||
# Copyright 2013 The Lmath Developers. For a full listing of the authors,
|
|
||||||
# refer to the AUTHORS file at the top-level directory of this distribution.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
|
|
||||||
TARGET = lmath
|
|
||||||
|
|
||||||
ROOT_DIR = .
|
|
||||||
|
|
||||||
SRC_DIR = $(ROOT_DIR)/src
|
|
||||||
SRC_CRATE = $(TARGET).rs
|
|
||||||
EXTERN_DIR = $(ROOT_DIR)/extern
|
|
||||||
BUILD_DIR = $(ROOT_DIR)/lib
|
|
||||||
|
|
||||||
CFG = --cfg=bounds --cfg=transform --cfg=space
|
|
||||||
|
|
||||||
TEST = $(TARGET)
|
|
||||||
TEST_BUILD_DIR = $(ROOT_DIR)/test
|
|
||||||
|
|
||||||
.PHONY: test
|
|
||||||
|
|
||||||
$(TARGET):
|
|
||||||
@echo "Building $(TARGET)..."
|
|
||||||
@mkdir -p $(BUILD_DIR)
|
|
||||||
@rustc $(CFG) $(SRC_DIR)/$(SRC_CRATE) --out-dir=$(BUILD_DIR)
|
|
||||||
@echo "Success"
|
|
||||||
|
|
||||||
all: $(TARGET)
|
|
||||||
|
|
||||||
test:
|
|
||||||
@echo "Building unit tests for $(TARGET)..."
|
|
||||||
@mkdir -p $(TEST_BUILD_DIR)
|
|
||||||
@rustc $(CFG) $(SRC_DIR)/$(SRC_CRATE) --test --out-dir=$(TEST_BUILD_DIR)
|
|
||||||
@echo "Success"
|
|
||||||
@$(TEST_BUILD_DIR)/$(TARGET)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -R -f $(BUILD_DIR)
|
|
||||||
rm -R -f $(TEST_BUILD_DIR)
|
|
12
README.md
12
README.md
|
@ -1,11 +1,3 @@
|
||||||
# Lmath-rs
|
# cgmath-rs
|
||||||
|
|
||||||
A mathematics library for computer graphics.
|
A linear algebra and mathematics library for computer graphics.
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
|
||||||
|
|
||||||
- [luqmana/rray](https://github.com/luqmana/rray) - Raytracer written in rust.
|
|
||||||
|
|
||||||
|
|
||||||
~B☼
|
|
||||||
|
|
|
@ -67,4 +67,6 @@ impl<T:Clone + Float> AABB3<T> {
|
||||||
size: mx - mn,
|
size: mx - mn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub fn intersects_aabb3(&self, other: &AABB3<T>) -> bool {}
|
||||||
}
|
}
|
|
@ -17,10 +17,11 @@
|
||||||
|
|
||||||
pub use self::aabb::{AABB2, AABB3};
|
pub use self::aabb::{AABB2, AABB3};
|
||||||
pub use self::frustum::{Frustum, FrustumPoints};
|
pub use self::frustum::{Frustum, FrustumPoints};
|
||||||
|
pub use self::obb::{OBB2, OBB3};
|
||||||
pub use self::sphere::Sphere;
|
pub use self::sphere::Sphere;
|
||||||
|
|
||||||
pub mod aabb;
|
pub mod aabb;
|
||||||
pub mod box;
|
|
||||||
pub mod cylinder;
|
pub mod cylinder;
|
||||||
pub mod frustum;
|
pub mod frustum;
|
||||||
|
pub mod obb;
|
||||||
pub mod sphere;
|
pub mod sphere;
|
|
@ -18,14 +18,14 @@
|
||||||
use math::*;
|
use math::*;
|
||||||
|
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Box2<T> {
|
pub struct OBB2<T> {
|
||||||
center: Point2<T>,
|
center: Point2<T>,
|
||||||
axis: Vec2<T>,
|
axis: Vec2<T>,
|
||||||
extents: Vec2<T>,
|
extents: Vec2<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Box3<T> {
|
pub struct OBB3<T> {
|
||||||
center: Point3<T>,
|
center: Point3<T>,
|
||||||
axis: Vec3<T>,
|
axis: Vec3<T>,
|
||||||
extents: Vec3<T>,
|
extents: Vec3<T>,
|
|
@ -75,6 +75,7 @@ pub type Mat2f32 = Mat2<f32>;
|
||||||
pub type Mat2f64 = Mat2<f64>;
|
pub type Mat2f64 = Mat2<f64>;
|
||||||
|
|
||||||
impl_dimensioned!(Mat2, Vec2<T>, 2)
|
impl_dimensioned!(Mat2, Vec2<T>, 2)
|
||||||
|
impl_swap_components!(Mat2)
|
||||||
impl_approx!(Mat3 { x, y, z })
|
impl_approx!(Mat3 { x, y, z })
|
||||||
|
|
||||||
pub trait ToMat2<T> {
|
pub trait ToMat2<T> {
|
||||||
|
@ -288,7 +289,7 @@ impl<T:Clone + Float> Mat2<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Float> FloatMat<T,Vec3<T>,[Vec3<T>,..3]> for Mat2<T> {
|
impl<T:Clone + Float> FloatMat<T,Vec2<T>,[Vec2<T>,..2]> for Mat2<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse(&self) -> Option<Mat2<T>> {
|
pub fn inverse(&self) -> Option<Mat2<T>> {
|
||||||
let d = self.determinant();
|
let d = self.determinant();
|
||||||
|
@ -539,6 +540,7 @@ pub type Mat3f32 = Mat3<f32>;
|
||||||
pub type Mat3f64 = Mat3<f64>;
|
pub type Mat3f64 = Mat3<f64>;
|
||||||
|
|
||||||
impl_dimensioned!(Mat3, Vec3<T>, 3)
|
impl_dimensioned!(Mat3, Vec3<T>, 3)
|
||||||
|
impl_swap_components!(Mat3)
|
||||||
impl_approx!(Mat2 { x, y })
|
impl_approx!(Mat2 { x, y })
|
||||||
|
|
||||||
pub trait ToMat3<T> {
|
pub trait ToMat3<T> {
|
||||||
|
@ -761,7 +763,7 @@ impl<T:Clone + Num> Neg<Mat3<T>> for Mat3<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Float> Mat3<T> {
|
impl<T: Clone + Float> Mat3<T> {
|
||||||
pub fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> Mat3<T> {
|
pub fn look_at(dir: &Vec3<T>, up: &Vec3<T>) -> Mat3<T> {
|
||||||
let dir_ = dir.normalize();
|
let dir_ = dir.normalize();
|
||||||
let side = dir_.cross(&up.normalize());
|
let side = dir_.cross(&up.normalize());
|
||||||
|
@ -823,7 +825,7 @@ impl<T:Clone + Float> ToQuat<T> for Mat3<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Float> FloatMat<T,Vec4<T>,[Vec4<T>,..4]> for Mat3<T> {
|
impl<T:Clone + Float> FloatMat<T,Vec3<T>,[Vec3<T>,..3]> for Mat3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn inverse(&self) -> Option<Mat3<T>> {
|
pub fn inverse(&self) -> Option<Mat3<T>> {
|
||||||
let d = self.determinant();
|
let d = self.determinant();
|
||||||
|
@ -1111,6 +1113,7 @@ pub type Mat4f32 = Mat4<f32>;
|
||||||
pub type Mat4f64 = Mat4<f64>;
|
pub type Mat4f64 = Mat4<f64>;
|
||||||
|
|
||||||
impl_dimensioned!(Mat4, Vec4<T>, 4)
|
impl_dimensioned!(Mat4, Vec4<T>, 4)
|
||||||
|
impl_swap_components!(Mat4)
|
||||||
impl_approx!(Mat4 { x, y, z, w })
|
impl_approx!(Mat4 { x, y, z, w })
|
||||||
|
|
||||||
pub trait ToMat4<T> {
|
pub trait ToMat4<T> {
|
|
@ -22,7 +22,7 @@ pub trait Vec<T,Slice>: Dimensioned<T,Slice>
|
||||||
+ SwapComponents {}
|
+ SwapComponents {}
|
||||||
|
|
||||||
/// Vectors with numeric components
|
/// Vectors with numeric components
|
||||||
pub trait NumVec<T,Slice>: Neg<T> {
|
pub trait NumVec<T,Slice>: Neg<Self> {
|
||||||
pub fn add_s(&self, value: T) -> Self;
|
pub fn add_s(&self, value: T) -> Self;
|
||||||
pub fn sub_s(&self, value: T) -> Self;
|
pub fn sub_s(&self, value: T) -> Self;
|
||||||
pub fn mul_s(&self, value: T) -> Self;
|
pub fn mul_s(&self, value: T) -> Self;
|
||||||
|
@ -209,9 +209,9 @@ impl<T:Num> Vec2<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Vec<T,[T,..2]> for Vec2<T> {}
|
impl<T: Clone> Vec<T,[T,..2]> for Vec2<T> {}
|
||||||
|
|
||||||
impl<T:Num> NumVec<T,[T,..2]> for Vec2<T> {
|
impl<T: Clone + Num> NumVec<T,[T,..2]> for Vec2<T> {
|
||||||
/// Returns a new vector with `value` added to each component.
|
/// Returns a new vector with `value` added to each component.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_s(&self, value: T) -> Vec2<T> {
|
pub fn add_s(&self, value: T) -> Vec2<T> {
|
||||||
|
@ -371,7 +371,7 @@ impl<T:Num> NumVec<T,[T,..2]> for Vec2<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Num> Neg<Vec2<T>> for Vec2<T> {
|
impl<T: Clone + Num> Neg<Vec2<T>> for Vec2<T> {
|
||||||
/// Returns the vector with each component negated.
|
/// Returns the vector with each component negated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(&self) -> Vec2<T> {
|
pub fn neg(&self) -> Vec2<T> {
|
||||||
|
@ -380,7 +380,7 @@ impl<T:Num> Neg<Vec2<T>> for Vec2<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Float> FloatVec<T,[T,..2]> for Vec2<T> {
|
impl<T: Clone + Float> FloatVec<T,[T,..2]> for Vec2<T> {
|
||||||
/// Returns the squared magnitude of the vector. This does not perform a
|
/// Returns the squared magnitude of the vector. This does not perform a
|
||||||
/// square root operation like in the `magnitude` method and can therefore
|
/// square root operation like in the `magnitude` method and can therefore
|
||||||
/// be more efficient for comparing the magnitudes of two vectors.
|
/// be more efficient for comparing the magnitudes of two vectors.
|
||||||
|
@ -442,7 +442,7 @@ impl<T:Float> FloatVec<T,[T,..2]> for Vec2<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Orderable> OrdVec<T,[T,..2],Vec2<bool>> for Vec2<T> {
|
impl<T: Clone + Orderable> OrdVec<T,[T,..2],Vec2<bool>> for Vec2<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn lt_s(&self, value: T) -> Vec2<bool> {
|
pub fn lt_s(&self, value: T) -> Vec2<bool> {
|
||||||
Vec2::new(*self.i(0) < value,
|
Vec2::new(*self.i(0) < value,
|
||||||
|
@ -857,9 +857,9 @@ impl<T:Num> Vec3<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Vec<T,[T,..3]> for Vec3<T> {}
|
impl<T: Clone> Vec<T,[T,..3]> for Vec3<T> {}
|
||||||
|
|
||||||
impl<T:Num> NumVec<T,[T,..3]> for Vec3<T> {
|
impl<T: Clone + Num> NumVec<T,[T,..3]> for Vec3<T> {
|
||||||
/// Returns a new vector with `value` added to each component.
|
/// Returns a new vector with `value` added to each component.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_s(&self, value: T) -> Vec3<T> {
|
pub fn add_s(&self, value: T) -> Vec3<T> {
|
||||||
|
@ -1041,7 +1041,7 @@ impl<T:Num> NumVec<T,[T,..3]> for Vec3<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Num> Neg<Vec3<T>> for Vec3<T> {
|
impl<T: Clone + Num> Neg<Vec3<T>> for Vec3<T> {
|
||||||
/// Returns the vector with each component negated.
|
/// Returns the vector with each component negated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(&self) -> Vec3<T> {
|
pub fn neg(&self) -> Vec3<T> {
|
||||||
|
@ -1051,7 +1051,7 @@ impl<T:Num> Neg<Vec3<T>> for Vec3<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Float> FloatVec<T,[T,..3]> for Vec3<T> {
|
impl<T: Clone + Float> FloatVec<T,[T,..3]> for Vec3<T> {
|
||||||
/// Returns the squared magnitude of the vector. This does not perform a
|
/// Returns the squared magnitude of the vector. This does not perform a
|
||||||
/// square root operation like in the `magnitude` method and can therefore
|
/// square root operation like in the `magnitude` method and can therefore
|
||||||
/// be more efficient for comparing the magnitudes of two vectors.
|
/// be more efficient for comparing the magnitudes of two vectors.
|
||||||
|
@ -1113,7 +1113,7 @@ impl<T:Float> FloatVec<T,[T,..3]> for Vec3<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Orderable> OrdVec<T,[T,..3],Vec3<bool>> for Vec3<T> {
|
impl<T: Clone + Orderable> OrdVec<T,[T,..3],Vec3<bool>> for Vec3<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn lt_s(&self, value: T) -> Vec3<bool> {
|
pub fn lt_s(&self, value: T) -> Vec3<bool> {
|
||||||
Vec3::new(*self.i(0) < value,
|
Vec3::new(*self.i(0) < value,
|
||||||
|
@ -1541,9 +1541,9 @@ impl<T:Num> Vec4<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Vec<T,[T,..4]> for Vec4<T> {}
|
impl<T: Clone> Vec<T,[T,..4]> for Vec4<T> {}
|
||||||
|
|
||||||
impl<T:Num> NumVec<T,[T,..4]> for Vec4<T> {
|
impl<T: Clone + Num> NumVec<T,[T,..4]> for Vec4<T> {
|
||||||
/// Returns a new vector with `value` added to each component.
|
/// Returns a new vector with `value` added to each component.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn add_s(&self, value: T) -> Vec4<T> {
|
pub fn add_s(&self, value: T) -> Vec4<T> {
|
||||||
|
@ -1747,7 +1747,7 @@ impl<T:Num> NumVec<T,[T,..4]> for Vec4<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Num> Neg<Vec4<T>> for Vec4<T> {
|
impl<T: Clone + Num> Neg<Vec4<T>> for Vec4<T> {
|
||||||
/// Returns the vector with each component negated.
|
/// Returns the vector with each component negated.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn neg(&self) -> Vec4<T> {
|
pub fn neg(&self) -> Vec4<T> {
|
||||||
|
@ -1758,7 +1758,7 @@ impl<T:Num> Neg<Vec4<T>> for Vec4<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Float> FloatVec<T,[T,..4]> for Vec4<T> {
|
impl<T: Clone + Float> FloatVec<T,[T,..4]> for Vec4<T> {
|
||||||
/// Returns the squared magnitude of the vector. This does not perform a
|
/// Returns the squared magnitude of the vector. This does not perform a
|
||||||
/// square root operation like in the `magnitude` method and can therefore
|
/// square root operation like in the `magnitude` method and can therefore
|
||||||
/// be more efficient for comparing the magnitudes of two vectors.
|
/// be more efficient for comparing the magnitudes of two vectors.
|
||||||
|
@ -1820,7 +1820,7 @@ impl<T:Float> FloatVec<T,[T,..4]> for Vec4<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Orderable> OrdVec<T,[T,..4],Vec4<bool>> for Vec4<T> {
|
impl<T: Clone + Orderable> OrdVec<T,[T,..4],Vec4<bool>> for Vec4<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn lt_s(&self, value: T) -> Vec4<bool> {
|
pub fn lt_s(&self, value: T) -> Vec4<bool> {
|
||||||
Vec4::new(*self.i(0) < value,
|
Vec4::new(*self.i(0) < value,
|
|
@ -15,4 +15,9 @@
|
||||||
|
|
||||||
// http://gameprogrammingpatterns.com/spatial-partition.html
|
// http://gameprogrammingpatterns.com/spatial-partition.html
|
||||||
|
|
||||||
pub struct Octree;
|
use bounds::AABB3;
|
||||||
|
|
||||||
|
pub struct Octree<Elem,T> {
|
||||||
|
bounds: AABB3<T>,
|
||||||
|
octants: [Option<~Octree<Elem,T>>, ..8],
|
||||||
|
}
|
|
@ -52,7 +52,7 @@ pub trait Rotation3<T>: Eq
|
||||||
+ ToMat3<T>
|
+ ToMat3<T>
|
||||||
+ ToMat4<T>
|
+ ToMat4<T>
|
||||||
+ ToQuat<T> {
|
+ ToQuat<T> {
|
||||||
pub fn rotate_point3(&self, point: Point3<T>) -> Point3<T>;
|
pub fn rotate_point3(&self, point: &Point3<T>) -> Point3<T>;
|
||||||
pub fn rotate_vec3(&self, vec: &Vec3<T>) -> Vec3<T>;
|
pub fn rotate_vec3(&self, vec: &Vec3<T>) -> Vec3<T>;
|
||||||
pub fn rotate_ray3(&self, ray: &Ray3<T>) -> Ray3<T>;
|
pub fn rotate_ray3(&self, ray: &Ray3<T>) -> Ray3<T>;
|
||||||
pub fn to_rotation_mat3(&self) -> RotationMat3<T>;
|
pub fn to_rotation_mat3(&self) -> RotationMat3<T>;
|
||||||
|
@ -80,7 +80,7 @@ impl<T> RotationMat2<T> {
|
||||||
|
|
||||||
impl<T:Clone + Float> Rotation2<T> for RotationMat2<T> {
|
impl<T:Clone + Float> Rotation2<T> for RotationMat2<T> {
|
||||||
pub fn rotate_point2(&self, point: Point2<T>) -> Point2<T> {
|
pub fn rotate_point2(&self, point: Point2<T>) -> Point2<T> {
|
||||||
Point2::from_vec2(self.mat.mul_v(point.as_vec2()))
|
point.with_vec2(|vec| self.rotate_vec2(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotate_vec2(&self, vec: &Vec2<T>) -> Vec2<T> {
|
pub fn rotate_vec2(&self, vec: &Vec2<T>) -> Vec2<T> {
|
||||||
|
@ -121,8 +121,8 @@ impl<T:Clone + Num> Neg<RotationMat2<T>> for RotationMat2<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Float> Rotation3<T> for Quat<T> {
|
impl<T:Clone + Float> Rotation3<T> for Quat<T> {
|
||||||
pub fn rotate_point3(&self, point: Point3<T>) -> Point3<T> {
|
pub fn rotate_point3(&self, point: &Point3<T>) -> Point3<T> {
|
||||||
Point3::from_vec3(self.mul_v(point.as_vec3()))
|
point.with_vec3(|vec| self.rotate_vec3(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotate_vec3(&self, vec: &Vec3<T>) -> Vec3<T> {
|
pub fn rotate_vec3(&self, vec: &Vec3<T>) -> Vec3<T> {
|
||||||
|
@ -160,8 +160,8 @@ impl<T> RotationMat3<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Float> Rotation3<T> for RotationMat3<T> {
|
impl<T:Clone + Float> Rotation3<T> for RotationMat3<T> {
|
||||||
pub fn rotate_point3(&self, point: Point3<T>) -> Point3<T> {
|
pub fn rotate_point3(&self, point: &Point3<T>) -> Point3<T> {
|
||||||
Point3::from_vec3(self.mat.mul_v(point.as_vec3()))
|
point.with_vec3(|vec| self.rotate_vec3(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotate_vec3(&self, vec: &Vec3<T>) -> Vec3<T> {
|
pub fn rotate_vec3(&self, vec: &Vec3<T>) -> Vec3<T> {
|
||||||
|
@ -243,7 +243,7 @@ impl<T:Float> Euler<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Float> Rotation3<T> for Euler<T> {
|
impl<T:Clone + Float> Rotation3<T> for Euler<T> {
|
||||||
pub fn rotate_point3(&self, _point: Point3<T>) -> Point3<T> {
|
pub fn rotate_point3(&self, _point: &Point3<T>) -> Point3<T> {
|
||||||
fail!("Not yet implemented.")
|
fail!("Not yet implemented.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,12 +337,27 @@ impl<T:Float> AxisAngle<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Float> Rotation3<T> for AxisAngle<T> {
|
impl<T:Float> Rotation3<T> for AxisAngle<T> {
|
||||||
pub fn rotate_point3(&self, _point: Point3<T>) -> Point3<T> {
|
pub fn rotate_point3(&self, point: &Point3<T>) -> Point3<T> {
|
||||||
fail!("Not yet implemented.")
|
point.with_vec3(|vec| self.rotate_vec3(vec))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotate_vec3(&self, _vec: &Vec3<T>) -> Vec3<T> {
|
pub fn rotate_vec3(&self, vec: &Vec3<T>) -> Vec3<T> {
|
||||||
fail!("Not yet implemented.")
|
// Rodrigues' rotation formula
|
||||||
|
// http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
|
||||||
|
//
|
||||||
|
// ~~~
|
||||||
|
// v cos θ + (k × v) sin θ + k(k ⋅ v)(1 - cos θ)
|
||||||
|
// ~~~
|
||||||
|
//
|
||||||
|
// Where:
|
||||||
|
// - `v` = vec
|
||||||
|
// - `k` = self.axis
|
||||||
|
// - `θ` = self.angle
|
||||||
|
|
||||||
|
vec.mul_s(self.angle.cos())
|
||||||
|
.add_v(&self.axis.cross(vec)).mul_s(self.angle.sin())
|
||||||
|
.add_v(&self.axis.mul_s(self.axis.dot(vec))
|
||||||
|
.mul_s(one!(T) - self.angle.cos()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotate_ray3(&self, _ray: &Ray3<T>) -> Ray3<T> {
|
pub fn rotate_ray3(&self, _ray: &Ray3<T>) -> Ray3<T> {
|
||||||
|
@ -434,7 +449,7 @@ pub struct AngleX<T>(T);
|
||||||
impl_approx!(AngleX)
|
impl_approx!(AngleX)
|
||||||
|
|
||||||
impl<T:Clone + Float> Rotation3<T> for AngleX<T> {
|
impl<T:Clone + Float> Rotation3<T> for AngleX<T> {
|
||||||
pub fn rotate_point3(&self, _point: Point3<T>) -> Point3<T> {
|
pub fn rotate_point3(&self, _point: &Point3<T>) -> Point3<T> {
|
||||||
fail!("Not yet implemented.")
|
fail!("Not yet implemented.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,7 +510,7 @@ pub struct AngleY<T>(T);
|
||||||
impl_approx!(AngleY)
|
impl_approx!(AngleY)
|
||||||
|
|
||||||
impl<T:Clone + Float> Rotation3<T> for AngleY<T> {
|
impl<T:Clone + Float> Rotation3<T> for AngleY<T> {
|
||||||
pub fn rotate_point3(&self, _point: Point3<T>) -> Point3<T> {
|
pub fn rotate_point3(&self, _point: &Point3<T>) -> Point3<T> {
|
||||||
fail!("Not yet implemented.")
|
fail!("Not yet implemented.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,7 +590,7 @@ impl<T:Float> Rotation2<T> for AngleZ<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T:Clone + Float> Rotation3<T> for AngleZ<T> {
|
impl<T:Clone + Float> Rotation3<T> for AngleZ<T> {
|
||||||
pub fn rotate_point3(&self, _point: Point3<T>) -> Point3<T> {
|
pub fn rotate_point3(&self, _point: &Point3<T>) -> Point3<T> {
|
||||||
fail!("Not yet implemented.")
|
fail!("Not yet implemented.")
|
||||||
}
|
}
|
||||||
|
|
26
src/cgmath.rs
Normal file
26
src/cgmath.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2013 The CGMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#[link(name = "cgmath",
|
||||||
|
vers = "0.1",
|
||||||
|
author = "Brendan Zabarauskas",
|
||||||
|
url = "https://github.com/bjz/cgmath-rs")];
|
||||||
|
|
||||||
|
#[comment = "A mathematics library for computer graphics."];
|
||||||
|
#[license = "ASL2"];
|
||||||
|
#[crate_type = "lib"];
|
||||||
|
|
||||||
|
pub mod traits;
|
||||||
|
pub mod types;
|
25
src/traits/alg/affine_space.rs
Normal file
25
src/traits/alg/affine_space.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::num::Zero;
|
||||||
|
|
||||||
|
use traits::alg::ScalarMul;
|
||||||
|
|
||||||
|
/// An affine space is a set of points closed under affine combinations.
|
||||||
|
pub trait AffineSpace<S,V>: Eq
|
||||||
|
+ Zero
|
||||||
|
+ ScalarMul<S>
|
||||||
|
+ Add<V, Self>
|
||||||
|
+ Sub<Self, V> {}
|
20
src/traits/alg/coordinate.rs
Normal file
20
src/traits/alg/coordinate.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
pub use traits::util::Indexable;
|
||||||
|
pub use traits::util::Swappable;
|
||||||
|
|
||||||
|
pub trait Coordinate<S, Slice>: Indexable<S, Slice>
|
||||||
|
+ Swappable<S, Slice> {}
|
37
src/traits/alg/division_ring.rs
Normal file
37
src/traits/alg/division_ring.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
// Copyright 2013 The Lmath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use traits::alg::Ring;
|
||||||
|
|
||||||
|
/// A ring that also requires the multiplicative inverse operation (division).
|
||||||
|
pub trait DivisionRing: Ring
|
||||||
|
+ Div<Self,Self>
|
||||||
|
+ Rem<Self,Self> {}
|
||||||
|
|
||||||
|
// impls for concrete types
|
||||||
|
|
||||||
|
impl DivisionRing for u8;
|
||||||
|
impl DivisionRing for u16;
|
||||||
|
impl DivisionRing for u32;
|
||||||
|
impl DivisionRing for u64;
|
||||||
|
impl DivisionRing for uint;
|
||||||
|
impl DivisionRing for i8;
|
||||||
|
impl DivisionRing for i16;
|
||||||
|
impl DivisionRing for i32;
|
||||||
|
impl DivisionRing for i64;
|
||||||
|
impl DivisionRing for int;
|
||||||
|
impl DivisionRing for f32;
|
||||||
|
impl DivisionRing for f64;
|
||||||
|
impl DivisionRing for float;
|
64
src/traits/alg/euclidean_space.rs
Normal file
64
src/traits/alg/euclidean_space.rs
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::num;
|
||||||
|
|
||||||
|
use traits::alg::Ring;
|
||||||
|
use traits::alg::InnerProductSpace;
|
||||||
|
|
||||||
|
/// The Euclidean space is a vector space over the Real numbers.
|
||||||
|
pub trait EuclideanSpace<S:Real + Ring>: InnerProductSpace<S> {
|
||||||
|
fn dot(&self, other: &Self) -> S {
|
||||||
|
self.inner(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if the vector is perpendicular (at right angles to)
|
||||||
|
/// the other vector.
|
||||||
|
fn is_perpendicular(&self, other: &Self) -> bool {
|
||||||
|
self.is_orthogonal(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the squared length of the vector. This does not perform an
|
||||||
|
/// expensive square root operation like in the `length` method and can
|
||||||
|
/// therefore be more efficient for comparing the lengths of two vectors.
|
||||||
|
fn length2(&self) -> S {
|
||||||
|
self.dot(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The norm of the vector.
|
||||||
|
fn length(&self) -> S {
|
||||||
|
num::sqrt(self.dot(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The angle between the vector and `other`.
|
||||||
|
fn angle(&self, other: &Self) -> S;
|
||||||
|
|
||||||
|
/// Returns a vector with the same direction, but with a `length` (or
|
||||||
|
/// `norm`) of `1`.
|
||||||
|
fn normalize(&self) -> Self {
|
||||||
|
self.normalize_to(num::one::<S>())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a vector with the same direction and a given `length`.
|
||||||
|
fn normalize_to(&self, length: S) -> Self {
|
||||||
|
*self * (length / self.length())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the result of linarly interpolating the length of the vector
|
||||||
|
/// to the length of `other` by the specified amount.
|
||||||
|
fn lerp(&self, other: &Self, amount: S) -> Self {
|
||||||
|
*self + (*other - *self) * amount
|
||||||
|
}
|
||||||
|
}
|
24
src/traits/alg/inner_product_space.rs
Normal file
24
src/traits/alg/inner_product_space.rs
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use traits::alg::Ring;
|
||||||
|
use traits::alg::VectorSpace;
|
||||||
|
|
||||||
|
/// A vector space with the inner product operation.
|
||||||
|
pub trait InnerProductSpace<S: Ring>: VectorSpace<S> {
|
||||||
|
fn norm(&self) -> S;
|
||||||
|
fn inner(&self, other: &Self) -> S;
|
||||||
|
fn is_orthogonal(&self, other: &Self) -> bool;
|
||||||
|
}
|
36
src/traits/alg/mod.rs
Normal file
36
src/traits/alg/mod.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
pub use self::affine_space::AffineSpace;
|
||||||
|
pub use self::coordinate::Coordinate;
|
||||||
|
pub use self::division_ring::DivisionRing;
|
||||||
|
pub use self::euclidean_space::EuclideanSpace;
|
||||||
|
pub use self::inner_product_space::InnerProductSpace;
|
||||||
|
pub use self::module::Module;
|
||||||
|
pub use self::ordered_ring::OrderedRing;
|
||||||
|
pub use self::ring::Ring;
|
||||||
|
pub use self::scalar_mul::ScalarMul;
|
||||||
|
pub use self::vector_space::VectorSpace;
|
||||||
|
|
||||||
|
pub mod affine_space;
|
||||||
|
pub mod coordinate;
|
||||||
|
pub mod division_ring;
|
||||||
|
pub mod euclidean_space;
|
||||||
|
pub mod inner_product_space;
|
||||||
|
pub mod module;
|
||||||
|
pub mod ordered_ring;
|
||||||
|
pub mod ring;
|
||||||
|
pub mod scalar_mul;
|
||||||
|
pub mod vector_space;
|
40
src/traits/alg/module.rs
Normal file
40
src/traits/alg/module.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright 2013 The Lmath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::num::Zero;
|
||||||
|
|
||||||
|
use traits::alg::ScalarMul;
|
||||||
|
|
||||||
|
/// An algebraic structure that generalizes the notion of a vector space.
|
||||||
|
pub trait Module<S>: Eq
|
||||||
|
+ Add<Self,Self>
|
||||||
|
+ ScalarMul<S>
|
||||||
|
+ Zero {}
|
||||||
|
|
||||||
|
// impls for concrete types
|
||||||
|
|
||||||
|
impl Module<u8> for u8;
|
||||||
|
impl Module<u16> for u16;
|
||||||
|
impl Module<u32> for u32;
|
||||||
|
impl Module<u64> for u64;
|
||||||
|
impl Module<uint> for uint;
|
||||||
|
impl Module<i8> for i8;
|
||||||
|
impl Module<i16> for i16;
|
||||||
|
impl Module<i32> for i32;
|
||||||
|
impl Module<i64> for i64;
|
||||||
|
impl Module<int> for int;
|
||||||
|
impl Module<f32> for f32;
|
||||||
|
impl Module<f64> for f64;
|
||||||
|
impl Module<float> for float;
|
36
src/traits/alg/ordered_ring.rs
Normal file
36
src/traits/alg/ordered_ring.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2013 The Lmath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use traits::alg::Ring;
|
||||||
|
|
||||||
|
/// A ring that can also be ordered.
|
||||||
|
pub trait OrderedRing: Ring
|
||||||
|
+ Orderable {}
|
||||||
|
|
||||||
|
// impls for concrete types
|
||||||
|
|
||||||
|
impl OrderedRing for u8;
|
||||||
|
impl OrderedRing for u16;
|
||||||
|
impl OrderedRing for u32;
|
||||||
|
impl OrderedRing for u64;
|
||||||
|
impl OrderedRing for uint;
|
||||||
|
impl OrderedRing for i8;
|
||||||
|
impl OrderedRing for i16;
|
||||||
|
impl OrderedRing for i32;
|
||||||
|
impl OrderedRing for i64;
|
||||||
|
impl OrderedRing for int;
|
||||||
|
impl OrderedRing for f32;
|
||||||
|
impl OrderedRing for f64;
|
||||||
|
impl OrderedRing for float;
|
41
src/traits/alg/ring.rs
Normal file
41
src/traits/alg/ring.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2013 The Lmath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::num::One;
|
||||||
|
|
||||||
|
use traits::alg::Module;
|
||||||
|
|
||||||
|
/// A module that also requires the additive inverse operation (subtraction)
|
||||||
|
/// and the additive inverse.
|
||||||
|
pub trait Ring: Module<Self>
|
||||||
|
+ Neg<Self>
|
||||||
|
+ Sub<Self,Self>
|
||||||
|
+ One {}
|
||||||
|
|
||||||
|
// impls for concrete types
|
||||||
|
|
||||||
|
impl Ring for u8;
|
||||||
|
impl Ring for u16;
|
||||||
|
impl Ring for u32;
|
||||||
|
impl Ring for u64;
|
||||||
|
impl Ring for uint;
|
||||||
|
impl Ring for i8;
|
||||||
|
impl Ring for i16;
|
||||||
|
impl Ring for i32;
|
||||||
|
impl Ring for i64;
|
||||||
|
impl Ring for int;
|
||||||
|
impl Ring for f32;
|
||||||
|
impl Ring for f64;
|
||||||
|
impl Ring for float;
|
35
src/traits/alg/scalar_mul.rs
Normal file
35
src/traits/alg/scalar_mul.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// Copyright 2013 The Lmath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
/// Enforces the multiplication of an type by a scalar.
|
||||||
|
pub trait ScalarMul<S>: Mul<S, Self>
|
||||||
|
+ Div<S, Self>
|
||||||
|
+ Rem<S, Self> {}
|
||||||
|
|
||||||
|
// impls for concrete types
|
||||||
|
|
||||||
|
impl ScalarMul<u8> for u8;
|
||||||
|
impl ScalarMul<u16> for u16;
|
||||||
|
impl ScalarMul<u32> for u32;
|
||||||
|
impl ScalarMul<u64> for u64;
|
||||||
|
impl ScalarMul<uint> for uint;
|
||||||
|
impl ScalarMul<i8> for i8;
|
||||||
|
impl ScalarMul<i16> for i16;
|
||||||
|
impl ScalarMul<i32> for i32;
|
||||||
|
impl ScalarMul<i64> for i64;
|
||||||
|
impl ScalarMul<int> for int;
|
||||||
|
impl ScalarMul<f32> for f32;
|
||||||
|
impl ScalarMul<f64> for f64;
|
||||||
|
impl ScalarMul<float> for float;
|
22
src/traits/alg/vector_space.rs
Normal file
22
src/traits/alg/vector_space.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use traits::alg::Module;
|
||||||
|
|
||||||
|
/// A vector space is a set that is closed under vector addition and
|
||||||
|
/// scalar multiplication.
|
||||||
|
pub trait VectorSpace<S>: Module<S>
|
||||||
|
+ Neg<Self>
|
||||||
|
+ Sub<Self,Self> {}
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2013 The Lmath Developers. For a full listing of the authors,
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
// refer to the AUTHORS file at the top-level directory of this distribution.
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
//
|
//
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@ -13,6 +13,6 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#[pkg_crate(file = "src/lmath.rs")];
|
pub use self::vector_ext::VectorExt;
|
||||||
#[pkg(id = "lmath", vers = "0.1.0")];
|
|
||||||
#[pkg_dep(url = "git://github.com/bjz/numeric-rs")];
|
pub mod vector_ext;
|
49
src/traits/ext/vector_ext.rs
Normal file
49
src/traits/ext/vector_ext.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use traits::alg::Ring;
|
||||||
|
use traits::alg::VectorSpace;
|
||||||
|
use traits::util::Indexable;
|
||||||
|
|
||||||
|
pub trait VectorExt<S: Ring, Slice>: VectorSpace<S>
|
||||||
|
+ Indexable<S, Slice> {
|
||||||
|
#[inline] fn add_s(&self, s: S) -> Self { self.map(|x| x.add(&s)) }
|
||||||
|
#[inline] fn sub_s(&self, s: S) -> Self { self.map(|x| x.sub(&s)) }
|
||||||
|
#[inline] fn mul_s(&self, s: S) -> Self { self.map(|x| x.mul(&s)) }
|
||||||
|
#[inline] fn div_s(&self, s: S) -> Self { self.map(|x| x.div(&s)) }
|
||||||
|
#[inline] fn rem_s(&self, s: S) -> Self { self.map(|x| x.rem(&s)) }
|
||||||
|
|
||||||
|
#[inline] fn add_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.add(b) ) }
|
||||||
|
#[inline] fn sub_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.sub(b) ) }
|
||||||
|
#[inline] fn mul_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.mul(b) ) }
|
||||||
|
#[inline] fn div_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.div(b) ) }
|
||||||
|
#[inline] fn rem_v(&self, other: &Self) -> Self { self.bimap(other, |a, b| a.rem(b) ) }
|
||||||
|
|
||||||
|
#[inline] fn neg_self(&mut self) { self.map_mut(|x| *x = -*x); }
|
||||||
|
#[inline] fn add_self_s(&mut self, s: S) { self.map_mut(|x| *x = x.add(&s)); }
|
||||||
|
#[inline] fn sub_self_s(&mut self, s: S) { self.map_mut(|x| *x = x.sub(&s)); }
|
||||||
|
#[inline] fn mul_self_s(&mut self, s: S) { self.map_mut(|x| *x = x.mul(&s)); }
|
||||||
|
#[inline] fn div_self_s(&mut self, s: S) { self.map_mut(|x| *x = x.div(&s)); }
|
||||||
|
#[inline] fn rem_self_s(&mut self, s: S) { self.map_mut(|x| *x = x.rem(&s)); }
|
||||||
|
|
||||||
|
#[inline] fn add_self_v(&mut self, other: &Self) { self.bimap_mut::<S, Slice, Self>(other, |a, b| *a = a.add(b)) }
|
||||||
|
#[inline] fn sub_self_v(&mut self, other: &Self) { self.bimap_mut::<S, Slice, Self>(other, |a, b| *a = a.sub(b)) }
|
||||||
|
#[inline] fn mul_self_v(&mut self, other: &Self) { self.bimap_mut::<S, Slice, Self>(other, |a, b| *a = a.mul(b)) }
|
||||||
|
#[inline] fn div_self_v(&mut self, other: &Self) { self.bimap_mut::<S, Slice, Self>(other, |a, b| *a = a.div(b)) }
|
||||||
|
#[inline] fn rem_self_v(&mut self, other: &Self) { self.bimap_mut::<S, Slice, Self>(other, |a, b| *a = a.rem(b)) }
|
||||||
|
|
||||||
|
#[inline] fn comp_add(&self) -> S { fail!() }
|
||||||
|
#[inline] fn comp_mul(&self) -> S { fail!() }
|
||||||
|
}
|
45
src/traits/mod.rs
Normal file
45
src/traits/mod.rs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#[macro_escape];
|
||||||
|
|
||||||
|
/// Import this module for the strict, algebraic trait heirachy.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~rust
|
||||||
|
/// use lmath::traits::alg::*;
|
||||||
|
/// ~~~
|
||||||
|
pub mod alg;
|
||||||
|
|
||||||
|
/// Import this module to access utility traits that do not neccsarily match
|
||||||
|
/// up with the strict algebraic properties of the respective types, and yet
|
||||||
|
/// still may be useful for computer graphics work.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~rust
|
||||||
|
/// use lmath::traits::ext::*;
|
||||||
|
/// ~~~
|
||||||
|
pub mod ext;
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ~~~rust
|
||||||
|
/// use lmath::traits::util::*;
|
||||||
|
/// ~~~
|
||||||
|
pub mod util;
|
105
src/traits/util/indexable.rs
Normal file
105
src/traits/util/indexable.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#[macro_escape];
|
||||||
|
|
||||||
|
/// Types that can be accessed via an unsigned index.
|
||||||
|
pub trait Indexable<T, Slice> {
|
||||||
|
fn len(&self) -> uint;
|
||||||
|
fn i<'a>(&'a self, i: uint) -> &'a T;
|
||||||
|
fn mut_i<'a>(&'a mut self, i: uint) -> &'a mut T;
|
||||||
|
fn as_slice<'a>(&'a self) -> &'a Slice;
|
||||||
|
fn as_mut_slice<'a>(&'a mut self) -> &'a mut Slice;
|
||||||
|
fn from_slice(slice: Slice) -> Self;
|
||||||
|
fn build(builder: &fn(i: uint) -> T) -> Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn map<U, SliceU, UU: Indexable<U, SliceU>>(&self, f: &fn(&T) -> U) -> UU {
|
||||||
|
Indexable::build(|i| f(self.i(i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn map_mut(&mut self, f: &fn(&mut T)) {
|
||||||
|
for i in range(0, self.len()) {
|
||||||
|
f(self.mut_i(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn bimap<U, SliceU, UU: Indexable<U, SliceU>,
|
||||||
|
V, SliceV, VV: Indexable<V, SliceV>>(&self, other: &UU, f: &fn(&T, &U) -> V) -> VV {
|
||||||
|
Indexable::build(|i| f(self.i(i), other.i(i)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn bimap_mut<U, SliceU, UU: Indexable<U, Slice>>(&mut self, other: &UU, f: &fn(&mut T, &U)) {
|
||||||
|
for i in range(0, self.len()) {
|
||||||
|
f(self.mut_i(i), other.i(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn fold<U>(&self, init: U, f: &fn(acc: &U, x: &T) -> U) -> U {
|
||||||
|
let mut acc = init;
|
||||||
|
for i in range(0, self.len()) {
|
||||||
|
acc = f(&acc, self.i(i));
|
||||||
|
}
|
||||||
|
acc
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_indexable(
|
||||||
|
($Self:ty, [$T:ident, ..$n:expr]) => (
|
||||||
|
impl<$T> Indexable<$T, [$T,..$n]> for $Self {
|
||||||
|
#[inline]
|
||||||
|
fn len(&self) -> uint { $n }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn i<'a>(&'a self, i: uint) -> &'a $T {
|
||||||
|
&'a self.as_slice()[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn mut_i<'a>(&'a mut self, i: uint) -> &'a mut $T {
|
||||||
|
&'a mut self.as_mut_slice()[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn as_slice<'a>(&'a self) -> &'a [$T,..$n] {
|
||||||
|
unsafe { ::std::cast::transmute(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [$T,..$n] {
|
||||||
|
unsafe { ::std::cast::transmute(self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn from_slice(slice: [$T,..$n]) -> $Self {
|
||||||
|
unsafe { ::std::cast::transmute(slice) }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn build(builder: &fn(i: uint) -> $T) -> $Self {
|
||||||
|
use std::unstable::intrinsics;
|
||||||
|
let mut s: [$T,..$n] = unsafe { intrinsics::uninit() };
|
||||||
|
for i in range::<uint>(0, $n) {
|
||||||
|
s[i] = builder(i);
|
||||||
|
}
|
||||||
|
Indexable::from_slice(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
22
src/traits/util/mod.rs
Normal file
22
src/traits/util/mod.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#[macro_escape];
|
||||||
|
|
||||||
|
pub use self::indexable::Indexable;
|
||||||
|
pub use self::swappable::Swappable;
|
||||||
|
|
||||||
|
pub mod indexable;
|
||||||
|
pub mod swappable;
|
26
src/traits/util/swappable.rs
Normal file
26
src/traits/util/swappable.rs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use traits::util::Indexable;
|
||||||
|
|
||||||
|
pub trait Swappable<T: Clone, Slice>: Indexable<T, Slice> {
|
||||||
|
/// Swap two elements of the type in place.
|
||||||
|
#[inline]
|
||||||
|
fn swap(&mut self, a: uint, b: uint) {
|
||||||
|
let tmp = self.i(a).clone();
|
||||||
|
*self.mut_i(a) = self.i(b).clone();
|
||||||
|
*self.mut_i(b) = tmp;
|
||||||
|
}
|
||||||
|
}
|
14
src/types/matrix.rs
Normal file
14
src/types/matrix.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
19
src/types/mod.rs
Normal file
19
src/types/mod.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
pub mod matrix;
|
||||||
|
pub mod point;
|
||||||
|
pub mod quaternion;
|
||||||
|
pub mod vector;
|
76
src/types/point.rs
Normal file
76
src/types/point.rs
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
//! Points are fixed positions in affine space with no length or direction. This
|
||||||
|
//! disinguishes them from vectors, which have a length and direction, but do
|
||||||
|
//! not have a fixed position.
|
||||||
|
|
||||||
|
use traits::alg::*;
|
||||||
|
use traits::util::*;
|
||||||
|
use types::vector::{Vec2, Vec3};
|
||||||
|
|
||||||
|
#[deriving(Eq, Zero, Clone)]
|
||||||
|
struct Point2<S> { x: S, y: S }
|
||||||
|
|
||||||
|
#[deriving(Eq, Zero, Clone)]
|
||||||
|
struct Point3<S> { x: S, y: S, z: S }
|
||||||
|
|
||||||
|
impl<S> Point2<S> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(x: S, y: S) -> Point2<S> {
|
||||||
|
Point2 { x: x, y: y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> Point3<S> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(x: S, y: S, z: S) -> Point3<S> {
|
||||||
|
Point3 { x: x, y: y, z: z }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operator impls
|
||||||
|
|
||||||
|
impl<S:Ring> Mul<S, Point2<S>> for Point2<S> { #[inline(always)] fn mul(&self, s: &S) -> Point2<S> { self.map(|x| x.mul(s)) } }
|
||||||
|
impl<S:Ring> Mul<S, Point3<S>> for Point3<S> { #[inline(always)] fn mul(&self, s: &S) -> Point3<S> { self.map(|x| x.mul(s)) } }
|
||||||
|
|
||||||
|
impl<S:Ring> Div<S, Point2<S>> for Point2<S> { #[inline(always)] fn div(&self, s: &S) -> Point2<S> { self.map(|x| x.div(s)) } }
|
||||||
|
impl<S:Ring> Div<S, Point3<S>> for Point3<S> { #[inline(always)] fn div(&self, s: &S) -> Point3<S> { self.map(|x| x.div(s)) } }
|
||||||
|
|
||||||
|
impl<S:Ring> Rem<S, Point2<S>> for Point2<S> { #[inline(always)] fn rem(&self, s: &S) -> Point2<S> { self.map(|x| x.rem(s)) } }
|
||||||
|
impl<S:Ring> Rem<S, Point3<S>> for Point3<S> { #[inline(always)] fn rem(&self, s: &S) -> Point3<S> { self.map(|x| x.rem(s)) } }
|
||||||
|
|
||||||
|
impl<S:Ring> Add<Vec2<S>, Point2<S>> for Point2<S> { #[inline(always)] fn add(&self, other: &Vec2<S>) -> Point2<S> { self.bimap(other, |a, b| a.add(b)) } }
|
||||||
|
impl<S:Ring> Add<Vec3<S>, Point3<S>> for Point3<S> { #[inline(always)] fn add(&self, other: &Vec3<S>) -> Point3<S> { self.bimap(other, |a, b| a.add(b)) } }
|
||||||
|
|
||||||
|
impl<S:Ring> Sub<Point2<S>, Vec2<S>> for Point2<S> { #[inline(always)] fn sub(&self, other: &Point2<S>) -> Vec2<S> { self.bimap(other, |a, b| a.sub(b)) } }
|
||||||
|
impl<S:Ring> Sub<Point3<S>, Vec3<S>> for Point3<S> { #[inline(always)] fn sub(&self, other: &Point3<S>) -> Vec3<S> { self.bimap(other, |a, b| a.sub(b)) } }
|
||||||
|
|
||||||
|
// Trait impls
|
||||||
|
|
||||||
|
impl_indexable!(Point2<T>, [T, ..2])
|
||||||
|
impl_indexable!(Point3<T>, [T, ..3])
|
||||||
|
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..2]> for Point2<S>;
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..3]> for Point3<S>;
|
||||||
|
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..2]> for Point2<S>;
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..3]> for Point3<S>;
|
||||||
|
|
||||||
|
impl<S: Ring> ScalarMul<S> for Point2<S>;
|
||||||
|
impl<S: Ring> ScalarMul<S> for Point3<S>;
|
||||||
|
|
||||||
|
impl<S: Ring> AffineSpace<S, Vec2<S>> for Point2<S>;
|
||||||
|
impl<S: Ring> AffineSpace<S, Vec3<S>> for Point3<S>;
|
36
src/types/quaternion.rs
Normal file
36
src/types/quaternion.rs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use traits::alg::*;
|
||||||
|
use types::vector::Vec3;
|
||||||
|
|
||||||
|
/// A quaternion in scalar/vector form
|
||||||
|
#[deriving(Clone, Eq)]
|
||||||
|
pub struct Quat<T> { s: T, v: Vec3<T> }
|
||||||
|
|
||||||
|
impl<T: Ring> Quat<T> {
|
||||||
|
/// Construct a new quaternion from one scalar component and three
|
||||||
|
/// imaginary components
|
||||||
|
#[inline]
|
||||||
|
pub fn new(w: T, xi: T, yj: T, zk: T) -> Quat<T> {
|
||||||
|
Quat::from_sv(w, Vec3::new(xi, yj, zk))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Construct a new quaternion from a scalar and a vector
|
||||||
|
#[inline]
|
||||||
|
pub fn from_sv(s: T, v: Vec3<T>) -> Quat<T> {
|
||||||
|
Quat { s: s, v: v }
|
||||||
|
}
|
||||||
|
}
|
240
src/types/vector.rs
Normal file
240
src/types/vector.rs
Normal file
|
@ -0,0 +1,240 @@
|
||||||
|
// Copyright 2013 The OMath Developers. For a full listing of the authors,
|
||||||
|
// refer to the AUTHORS file at the top-level directory of this distribution.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::num;
|
||||||
|
use std::num::{Zero, zero};
|
||||||
|
use std::num::{sqrt, atan2};
|
||||||
|
|
||||||
|
use traits::alg::*;
|
||||||
|
use traits::ext::*;
|
||||||
|
use traits::util::*;
|
||||||
|
|
||||||
|
#[deriving(Eq, Zero, Clone)] pub struct Vec1<S> { x: S }
|
||||||
|
#[deriving(Eq, Zero, Clone)] pub struct Vec2<S> { x: S, y: S }
|
||||||
|
#[deriving(Eq, Zero, Clone)] pub struct Vec3<S> { x: S, y: S, z: S }
|
||||||
|
#[deriving(Eq, Zero, Clone)] pub struct Vec4<S> { x: S, y: S, z: S, w: S }
|
||||||
|
#[deriving(Eq, Zero, Clone)] pub struct Vec5<S> { x: S, y: S, z: S, w: S, a: S }
|
||||||
|
#[deriving(Eq, Zero, Clone)] pub struct Vec6<S> { x: S, y: S, z: S, w: S, a: S, b: S }
|
||||||
|
|
||||||
|
macro_rules! impl_vec(
|
||||||
|
($Self:ident <$S:ident> { $($field:ident),+ }) => (
|
||||||
|
impl<$S> $Self<$S> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new($($field: $S),+) -> $Self<$S> {
|
||||||
|
$Self { $($field: $field),+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
impl_vec!(Vec1<S> { x })
|
||||||
|
impl_vec!(Vec2<S> { x, y })
|
||||||
|
impl_vec!(Vec3<S> { x, y, z })
|
||||||
|
impl_vec!(Vec4<S> { x, y, z, w })
|
||||||
|
impl_vec!(Vec5<S> { x, y, z, w, a })
|
||||||
|
impl_vec!(Vec6<S> { x, y, z, w, a, b })
|
||||||
|
|
||||||
|
macro_rules! impl_vec_clonable(
|
||||||
|
($Self:ident <$S:ident>) => (
|
||||||
|
impl<$S:Clone> $Self<$S> {
|
||||||
|
/// Construct a vector from a single value.
|
||||||
|
#[inline]
|
||||||
|
pub fn from_value(value: $S) -> $Self<$S> {
|
||||||
|
Indexable::build(|_| value.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
impl_vec_clonable!(Vec1<S>)
|
||||||
|
impl_vec_clonable!(Vec2<S>)
|
||||||
|
impl_vec_clonable!(Vec3<S>)
|
||||||
|
impl_vec_clonable!(Vec4<S>)
|
||||||
|
impl_vec_clonable!(Vec5<S>)
|
||||||
|
impl_vec_clonable!(Vec6<S>)
|
||||||
|
|
||||||
|
macro_rules! impl_vec_ring(
|
||||||
|
($Self:ident <$S:ident>) => (
|
||||||
|
impl<$S:Ring> $Self<$S> {
|
||||||
|
/// The additive identity of the vector.
|
||||||
|
#[inline]
|
||||||
|
pub fn zero() -> $Self<$S> { zero() }
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
impl_vec_ring!(Vec1<S>)
|
||||||
|
impl_vec_ring!(Vec2<S>)
|
||||||
|
impl_vec_ring!(Vec3<S>)
|
||||||
|
impl_vec_ring!(Vec4<S>)
|
||||||
|
impl_vec_ring!(Vec5<S>)
|
||||||
|
impl_vec_ring!(Vec6<S>)
|
||||||
|
|
||||||
|
// Operator impls
|
||||||
|
|
||||||
|
macro_rules! impl_vec_ops(
|
||||||
|
($vec_ops_mod:ident, $Self:ident <$S:ident>) => (
|
||||||
|
pub mod $vec_ops_mod {
|
||||||
|
use super::*;
|
||||||
|
use super::super::super::traits::alg::*;
|
||||||
|
|
||||||
|
impl<$S:Ring> Mul<$S, $Self<$S>> for $Self<$S> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn mul(&self, s: &$S) -> $Self<$S> { self.map(|x| x.mul(s)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$S:Ring> Div<$S, $Self<$S>> for $Self<$S> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn div(&self, s: &$S) -> $Self<$S> { self.map(|x| x.div(s)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$S:Ring> Rem<$S, $Self<$S>> for $Self<$S> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn rem(&self, s: &$S) -> $Self<$S> { self.map(|x| x.rem(s)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$S:Ring> Add<$Self<$S>, $Self<$S>> for $Self<$S> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn add(&self, other: &$Self<$S>) -> $Self<$S> { self.bimap(other, |a, b| a.add(b)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$S:Ring> Sub<$Self<$S>, $Self<$S>> for $Self<$S> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn sub(&self, other: &$Self<$S>) -> $Self<$S> { self.bimap(other, |a, b| a.sub(b)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<$S:Ring> Neg<$Self<$S>> for $Self<$S> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn neg(&self) -> $Self<$S> { self.map(|x| x.neg()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
impl_vec_ops!(vec1_ops, Vec1<S>)
|
||||||
|
impl_vec_ops!(vec2_ops, Vec2<S>)
|
||||||
|
impl_vec_ops!(vec3_ops, Vec3<S>)
|
||||||
|
impl_vec_ops!(vec4_ops, Vec4<S>)
|
||||||
|
impl_vec_ops!(vec5_ops, Vec5<S>)
|
||||||
|
impl_vec_ops!(vec6_ops, Vec6<S>)
|
||||||
|
|
||||||
|
/// Operations specific to two-dimensional vectors.
|
||||||
|
impl<S: Ring> Vec2<S> {
|
||||||
|
/// The perpendicular dot product of the vector and `other`.
|
||||||
|
pub fn perp_dot(&self, other: &Vec2<S>) -> S {
|
||||||
|
(self.x * other.y) - (self.y * other.x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Operations specific to three-dimensional vectors.
|
||||||
|
impl<S: Ring> Vec3<S> {
|
||||||
|
/// Returns the cross product of the vector and `other`.
|
||||||
|
pub fn cross(&self, other: &Vec3<S>) -> Vec3<S> {
|
||||||
|
Vec3::new((self.y * other.z) - (self.z * other.y),
|
||||||
|
(self.z * other.x) - (self.x * other.z),
|
||||||
|
(self.x * other.y) - (self.y * other.x))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trait impls
|
||||||
|
|
||||||
|
impl_indexable!(Vec1<S>, [S, ..1])
|
||||||
|
impl_indexable!(Vec2<S>, [S, ..2])
|
||||||
|
impl_indexable!(Vec3<S>, [S, ..3])
|
||||||
|
impl_indexable!(Vec4<S>, [S, ..4])
|
||||||
|
impl_indexable!(Vec5<S>, [S, ..5])
|
||||||
|
impl_indexable!(Vec6<S>, [S, ..6])
|
||||||
|
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..1]> for Vec1<S>;
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..2]> for Vec2<S>;
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..3]> for Vec3<S>;
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..4]> for Vec4<S>;
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..5]> for Vec5<S>;
|
||||||
|
impl<S: Clone> Swappable<S, [S, ..6]> for Vec6<S>;
|
||||||
|
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..1]> for Vec1<S>;
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..2]> for Vec2<S>;
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..3]> for Vec3<S>;
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..4]> for Vec4<S>;
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..5]> for Vec5<S>;
|
||||||
|
impl<S: Clone> Coordinate<S, [S, ..6]> for Vec6<S>;
|
||||||
|
|
||||||
|
impl<S: Ring> ScalarMul<S> for Vec1<S>;
|
||||||
|
impl<S: Ring> ScalarMul<S> for Vec2<S>;
|
||||||
|
impl<S: Ring> ScalarMul<S> for Vec3<S>;
|
||||||
|
impl<S: Ring> ScalarMul<S> for Vec4<S>;
|
||||||
|
impl<S: Ring> ScalarMul<S> for Vec5<S>;
|
||||||
|
impl<S: Ring> ScalarMul<S> for Vec6<S>;
|
||||||
|
|
||||||
|
impl<S: Ring> Module<S> for Vec1<S>;
|
||||||
|
impl<S: Ring> Module<S> for Vec2<S>;
|
||||||
|
impl<S: Ring> Module<S> for Vec3<S>;
|
||||||
|
impl<S: Ring> Module<S> for Vec4<S>;
|
||||||
|
impl<S: Ring> Module<S> for Vec5<S>;
|
||||||
|
impl<S: Ring> Module<S> for Vec6<S>;
|
||||||
|
|
||||||
|
impl<S: Ring> VectorSpace<S> for Vec1<S>;
|
||||||
|
impl<S: Ring> VectorSpace<S> for Vec2<S>;
|
||||||
|
impl<S: Ring> VectorSpace<S> for Vec3<S>;
|
||||||
|
impl<S: Ring> VectorSpace<S> for Vec4<S>;
|
||||||
|
impl<S: Ring> VectorSpace<S> for Vec5<S>;
|
||||||
|
impl<S: Ring> VectorSpace<S> for Vec6<S>;
|
||||||
|
|
||||||
|
macro_rules! impl_vec_inner_product(
|
||||||
|
($Self:ident <$S:ident>) => (
|
||||||
|
impl<$S:Real + Ring + ApproxEq<$S>> InnerProductSpace<$S> for $Self<$S> {
|
||||||
|
fn norm(&self) -> $S {
|
||||||
|
num::sqrt(self.inner(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn inner(&self, other: &$Self<$S>) -> $S {
|
||||||
|
let comp_sum: $Self<$S> = self.bimap(other, |a, b| a.mul(b));
|
||||||
|
comp_sum.fold(num::zero::<$S>(), |a, b| a.add(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_orthogonal(&self, other: &$Self<$S>) -> bool {
|
||||||
|
self.inner(other).approx_eq(&num::zero())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
impl_vec_inner_product!(Vec1<S>)
|
||||||
|
impl_vec_inner_product!(Vec2<S>)
|
||||||
|
impl_vec_inner_product!(Vec3<S>)
|
||||||
|
impl_vec_inner_product!(Vec4<S>)
|
||||||
|
impl_vec_inner_product!(Vec5<S>)
|
||||||
|
impl_vec_inner_product!(Vec6<S>)
|
||||||
|
|
||||||
|
// Euclidean spaces only really make sense for 2D and 3D vector spaces
|
||||||
|
|
||||||
|
impl<S:Real + Ring + ApproxEq<S>> EuclideanSpace<S> for Vec2<S> {
|
||||||
|
fn angle(&self, other: &Vec2<S>) -> S {
|
||||||
|
atan2(self.perp_dot(other), self.dot(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S:Real + Ring + ApproxEq<S>> EuclideanSpace<S> for Vec3<S> {
|
||||||
|
fn angle(&self, other: &Vec3<S>) -> S {
|
||||||
|
atan2(self.cross(other).length(), self.dot(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S: Ring> VectorExt<S, [S, ..1]> for Vec1<S>;
|
||||||
|
impl<S: Ring> VectorExt<S, [S, ..2]> for Vec2<S>;
|
||||||
|
impl<S: Ring> VectorExt<S, [S, ..3]> for Vec3<S>;
|
||||||
|
impl<S: Ring> VectorExt<S, [S, ..4]> for Vec4<S>;
|
||||||
|
impl<S: Ring> VectorExt<S, [S, ..5]> for Vec5<S>;
|
||||||
|
impl<S: Ring> VectorExt<S, [S, ..6]> for Vec6<S>;
|
Loading…
Reference in a new issue