// 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. use angle::Angle; use array::Array; use matrix::{Mat2, ToMat2}; use matrix::{Mat3, ToMat3}; use point::{Point2, Point3}; use quaternion::ToQuat; use ray::{Ray2, Ray3}; use vector::{Vec2, Vec3}; /// A two-dimensional rotation pub trait Rotation2 < S > : Eq + ApproxEq + Neg + Add + Sub + ToMat2 + ToRot2 { fn rotate_point2(&self, point: Point2) -> Point2; fn rotate_vec2(&self, vec: &Vec2) -> Vec2; fn rotate_ray2(&self, ray: &Ray2) -> Ray2; } /// A three-dimensional rotation pub trait Rotation3 < S > : Eq + ApproxEq + Neg + Add + Sub + ToMat3 + ToRot3 + ToQuat { fn rotate_point3(&self, point: &Point3) -> Point3; fn rotate_vec3(&self, vec: &Vec3) -> Vec3; fn rotate_ray3(&self, ray: &Ray3) -> Ray3; } /// A two-dimensional rotation matrix. /// /// The matrix is guaranteed to be orthogonal, so some operations can be /// implemented more efficiently than the implementations for `math::Mat2`. To /// enforce orthogonality at the type level the operations have been restricted /// to a subeset of those implemented on `Mat2`. #[deriving(Eq, Clone)] pub struct Rot2 { priv mat: Mat2 } pub trait ToRot2 { fn to_rot2(&self) -> Rot2; } /// A three-dimensional rotation matrix. /// /// The matrix is guaranteed to be orthogonal, so some operations, specifically /// inversion, can be implemented more efficiently than the implementations for /// `math::Mat3`. To enforce orthogonality at the type level the operations have /// been restricted to a subeset of those implemented on `Mat3`. #[deriving(Eq, Clone)] pub struct Rot3 { priv mat: Mat3 } pub trait ToRot3 { fn to_rot3(&self) -> Rot3; } /// Euler angles /// /// Whilst Euler angles are easier to visualise, and more intuitive to specify, /// they are not reccomended for general use because they are prone to gimble /// lock. /// /// # Fields /// /// - `x`: the angular rotation around the `x` axis (pitch) /// - `y`: the angular rotation around the `y` axis (yaw) /// - `z`: the angular rotation around the `z` axis (roll) #[deriving(Eq, Clone)] pub struct Euler { x: A, y: A, z: A } array!(impl Euler -> [A, ..3]) pub trait ToEuler { fn to_euler(&self) -> Euler; } impl> Euler { #[inline] pub fn new(x: A, y: A, z: A) -> Euler { Euler { x: x, y: y, z: z } } } /// A rotation about an arbitrary axis #[deriving(Eq, Clone)] pub struct AxisAngle { axis: Vec3, angle: A, } /// An angle around the X axis (pitch). #[deriving(Eq, Ord, Clone)] pub struct AngleX(A); /// An angle around the X axis (yaw). #[deriving(Eq, Ord, Clone)] pub struct AngleY(A); /// An angle around the Z axis (roll). #[deriving(Eq, Ord, Clone)] pub struct AngleZ(A); impl> Neg> for AngleX { #[inline] fn neg(&self) -> AngleX { AngleX(-**self) } } impl> Neg> for AngleY { #[inline] fn neg(&self) -> AngleY { AngleY(-**self) } } impl> Neg> for AngleZ { #[inline] fn neg(&self) -> AngleZ { AngleZ(-**self) } } impl> Add, AngleX> for AngleX { #[inline] fn add(&self, other: &AngleX) -> AngleX { AngleX((**self).add_a(*other.clone())) } } impl> Add, AngleY> for AngleY { #[inline] fn add(&self, other: &AngleY) -> AngleY { AngleY((**self).add_a(*other.clone())) } } impl> Add, AngleZ> for AngleZ { #[inline] fn add(&self, other: &AngleZ) -> AngleZ { AngleZ((**self).add_a(*other.clone())) } } impl> Sub, AngleX> for AngleX { #[inline] fn sub(&self, other: &AngleX) -> AngleX { AngleX((**self).sub_a(*other.clone())) } } impl> Sub, AngleY> for AngleY { #[inline] fn sub(&self, other: &AngleY) -> AngleY { AngleY((**self).sub_a(*other.clone())) } } impl> Sub, AngleZ> for AngleZ { #[inline] fn sub(&self, other: &AngleZ) -> AngleZ { AngleZ((**self).sub_a(*other.clone())) } }