Homogeneous transformations added for Point3; extend/truncate added for vectors; Transform3 is implemented for AffineMatrix3

This commit is contained in:
kvark 2013-11-01 10:32:29 -04:00
parent 6dd06103fc
commit 04b257e217
6 changed files with 115 additions and 20 deletions

View file

@ -14,6 +14,7 @@
// limitations under the License.
use std::cast::transmute;
use std::fmt;
use intersect::Intersect;
use point::{Point, Point3};
@ -21,8 +22,6 @@ use ray::Ray3;
use vector::{Vec3, Vec4};
use vector::{Vector, EuclideanVector};
use std::fmt;
/// A 3-dimendional plane formed from the equation: `a*x + b*y + c*z - d = 0`.
///
/// # Fields

View file

@ -18,7 +18,7 @@
//! not have a fixed position.
use std::fmt;
use std::num::zero;
use std::num::{one,zero};
use array::*;
use vector::*;
@ -54,6 +54,19 @@ impl<S: Num> Point3<S> {
pub fn origin() -> Point3<S> { zero() }
}
impl<S: Clone + Num + Primitive> Point3<S> {
#[inline]
pub fn from_homogeneous(v: &Vec4<S>) -> Point3<S> {
let _1 :S = one();
let e = v.truncate().mul_s( _1 / v.w );
Point3::new(e.x.clone(), e.y.clone(), e.z.clone()) //FIXME
}
#[inline]
pub fn to_homogeneous(&self) -> Vec4<S> {
Vec4::new(self.x.clone(), self.y.clone(), self.z.clone(), one())
}
}
/// Specifies the numeric operations for point types.
pub trait Point
<

View file

@ -13,10 +13,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use matrix::Mat4;
use point::Point;
use std::num;
use matrix::{Matrix, Mat4, ToMat4};
use point::{Point, Point3};
use ray::Ray;
use rotation::Rotation;
use rotation::{Rotation, Rotation3};
use quaternion::Quat;
use vector::{Vector, Vec3};
@ -38,11 +40,6 @@ pub trait Transform
}
}
/// A homogeneous transformation matrix.
pub struct AffineMatrix3<S> {
mat: Mat4<S>,
}
/// A generic transformation consisting of a rotation,
/// displacement vector and scale amount.
pub struct Decomposed<S,V,R> {
@ -71,14 +68,56 @@ Transform<S, Slice, V, P> for Decomposed<S,V,R> {
}
}
/// A transformation in three dimensions consisting of a rotation,
/// displacement vector and scale amount.
pub struct Transform3<S>( Decomposed<S,Vec3<S>,Quat<S>> );
pub trait Transform3<S>
: Transform<S, [S, ..3], Vec3<S>, Point3<S>>
+ ToMat4<S>
{}
impl<S: Float> Transform3<S> {
#[inline]
pub fn new(scale: S, rot: Quat<S>, disp: Vec3<S>) -> Transform3<S> {
Transform3( Decomposed { scale: scale, rot: rot, disp: disp })
impl<S: Float + Clone, R: Rotation3<S>>
ToMat4<S> for Decomposed<S, Vec3<S>, R> {
fn to_mat4(&self) -> Mat4<S> {
let mut m = self.rot.to_mat3().mul_s( self.scale.clone() ).to_mat4();
m.w = self.disp.extend( num::one() );
m
}
}
impl<S: Float, R: Rotation3<S>>
Transform3<S> for Decomposed<S,Vec3<S>,R> {}
/// A homogeneous transformation matrix.
pub struct AffineMatrix3<S> {
mat: Mat4<S>,
}
impl<S : Clone + Float>
Transform<S, [S, ..3], Vec3<S>, Point3<S>> for AffineMatrix3<S> {
#[inline]
fn transform_vec(&self, vec: &Vec3<S>) -> Vec3<S> {
self.mat.mul_v( &vec.extend(num::zero()) ).truncate()
}
#[inline]
fn transform_point(&self, point: &Point3<S>) -> Point3<S> {
Point3::from_homogeneous( &self.mat.mul_v( &point.to_homogeneous() ))
}
}
impl<S: Clone + Primitive>
ToMat4<S> for AffineMatrix3<S> {
#[inline] fn to_mat4(&self) -> Mat4<S> { self.mat.clone() }
}
/// A transformation in three dimensions consisting of a rotation,
/// displacement vector and scale amount.
pub struct Transform3D<S>( Decomposed<S,Vec3<S>,Quat<S>> );
impl<S: Float> Transform3D<S> {
#[inline]
pub fn new(scale: S, rot: Quat<S>, disp: Vec3<S>) -> Transform3D<S> {
Transform3D( Decomposed { scale: scale, rot: rot, disp: disp })
}
}

View file

@ -31,7 +31,7 @@ pub struct Vec3<S> { x: S, y: S, z: S }
#[deriving(Eq, Clone, Zero)]
pub struct Vec4<S> { x: S, y: S, z: S, w: S }
// Conversion traits
// Conversion traits //FIXME: not used anywhere?
pub trait ToVec2<S: Primitive> { fn to_vec2(&self) -> Vec2<S>; }
pub trait ToVec3<S: Primitive> { fn to_vec3(&self) -> Vec3<S>; }
pub trait ToVec4<S: Primitive> { fn to_vec4(&self) -> Vec4<S>; }
@ -70,12 +70,28 @@ impl<S: Primitive> Vec2<S> {
#[inline] pub fn unit_x() -> Vec2<S> { Vec2::new(one(), zero()) }
#[inline] pub fn unit_y() -> Vec2<S> { Vec2::new(zero(), one()) }
}
impl<S: Primitive + Clone> Vec2<S> {
#[inline]
pub fn extend(&self, z: S)-> Vec3<S> {
Vec3::new(self.x.clone(), self.y.clone(), z)
}
}
impl<S: Primitive> Vec3<S> {
#[inline] pub fn unit_x() -> Vec3<S> { Vec3::new(one(), zero(), zero()) }
#[inline] pub fn unit_y() -> Vec3<S> { Vec3::new(zero(), one(), zero()) }
#[inline] pub fn unit_z() -> Vec3<S> { Vec3::new(zero(), zero(), one()) }
}
impl<S: Primitive + Clone> Vec3<S> {
#[inline]
pub fn extend(&self, w: S)-> Vec4<S> {
Vec4::new(self.x.clone(), self.y.clone(), self.z.clone(), w)
}
#[inline]
pub fn truncate(&self)-> Vec2<S> {
Vec2::new(self.x.clone(), self.y.clone()) //ignore Z
}
}
impl<S: Primitive> Vec4<S> {
#[inline] pub fn unit_x() -> Vec4<S> { Vec4::new(one(), zero(), zero(), zero()) }
@ -83,6 +99,12 @@ impl<S: Primitive> Vec4<S> {
#[inline] pub fn unit_z() -> Vec4<S> { Vec4::new(zero(), zero(), one(), zero()) }
#[inline] pub fn unit_w() -> Vec4<S> { Vec4::new(zero(), zero(), zero(), one()) }
}
impl<S: Primitive + Clone> Vec4<S> {
#[inline]
pub fn truncate(&self)-> Vec3<S> {
Vec3::new(self.x.clone(), self.y.clone(), self.z.clone()) //ignore W
}
}
array!(impl<S> Vec2<S> -> [S, ..2] _2)
array!(impl<S> Vec3<S> -> [S, ..3] _3)

22
src/tests/point.rs Normal file
View file

@ -0,0 +1,22 @@
// 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 cgmath::point::*;
#[test]
fn test_homogeneous() {
let p = Point3::new(1.0, 2.0, 3.0);
assert_eq!(p, Point3::from_homogeneous( &p.to_homogeneous() ));
}

View file

@ -22,7 +22,7 @@ pub mod vector;
pub mod angle;
pub mod plane;
// pub mod point;
pub mod point;
// pub mod ray;
// pub mod rotation;