Skip to content

Instantly share code, notes, and snippets.

@mstewartgallus
Created April 27, 2013 00:43
Show Gist options
  • Save mstewartgallus/5471387 to your computer and use it in GitHub Desktop.
Save mstewartgallus/5471387 to your computer and use it in GitHub Desktop.
Buggy matrix math code.
use core::num::*;
use std::complex::*;
use core::ops::*;
pub struct Vector { x : f32, y : f32 }
pub impl Vector {
fn from_scalar (scalar : f32) -> Vector { Vector { x : scalar, y : scalar } }
fn normal_to (vector : Vector) -> Vector {
Vector { x : -vector.y, y : vector.x }
}
}
impl Add <Vector, Vector> for Vector {
fn add (&self, rhs : &Vector) -> Vector {
Vector { x : self.x + rhs.x, y : self.y + rhs.y }
}
}
impl Sub <Vector, Vector> for Vector {
fn sub (&self, rhs : &Vector) -> Vector {
Vector { x : self.x - rhs.x, y : self.y - rhs.y }
}
}
impl Mul <Vector, Vector> for Vector {
fn mul (&self, rhs : &Vector) -> Vector {
Vector { x : self.x * rhs.x, y : self.y * rhs.y }
}
}
pub fn dot (lhs : Vector, rhs : Vector) -> f32 { lhs.x * rhs.x + lhs.y * rhs.y }
pub fn length (vector : Vector) -> f32 {
f32::sqrt (dot (vector, vector))
}
pub fn direction (vector : Vector) -> Vector {
let len = length (vector);
Vector { x : vector.x / len, y : vector.y / len }
}
#[deriving (Eq)]
pub struct Vector2 <T> { x : T, y : T }
#[deriving (Eq)]
pub struct RotationMultiplicationMatrix2x2 <T> (Cmplx <T>);
pub impl <T : Add <T, T> + Sub <T, T> + Mul <T, T>> RotationMultiplicationMatrix2x2 <T> {
// self = [a, -b], a rotation matrix, or a + ib
// [b, a]
fn rotate (self, Vector2 { x, y } : Vector2 <T>) -> Vector2 <T> {
let RotationMultiplicationMatrix2x2 (Cmplx { re, im }) = self;
Vector2 {
x : x * re - y * im,
y : x * im + y * re
}
}
}
pub type RotationMultiplicationMatrix4x4 <T> = RotationMultiplicationMatrix2x2 <RotationMultiplicationMatrix2x2 <T>>;
pub type Matrix2x2 <T> = RotationMultiplicationMatrix4x4 <T>;
pub impl <T> Matrix2x2 <T> {
fn new (
a : T, b : T,
c : T, d : T
) -> Matrix2x2 <T> {
// ((x +jy) + i(z + jw)) * _ = [[x, -y] [z, -w]] [[a, 0]] = [[]]
// [[y, x ], -[w, z ]] * [[0, a ]] [[]]
// [[z, -w] [x, -y]] [[c, 0]] [[]]
// [[w, z ], [y, x ]] [[0, c ]] [[]]
RotationMultiplicationMatrix2x2 (Cmplx {
re : RotationMultiplicationMatrix2x2 (Cmplx { re : a, im : b }),
im : RotationMultiplicationMatrix2x2 (Cmplx { re : c, im : d })
})
}
}
impl <T : Num + Copy> Add <RotationMultiplicationMatrix2x2 <T>, RotationMultiplicationMatrix2x2 <T>> for RotationMultiplicationMatrix2x2 <T> {
pub fn add (
&self,
matrix : &RotationMultiplicationMatrix2x2 <T>
) -> RotationMultiplicationMatrix2x2 <T> {
RotationMultiplicationMatrix2x2 (**self + **matrix)
}
}
impl <T : Num + Copy> Sub <RotationMultiplicationMatrix2x2 <T>, RotationMultiplicationMatrix2x2 <T>> for RotationMultiplicationMatrix2x2 <T> {
pub fn sub (
&self,
matrix : &RotationMultiplicationMatrix2x2 <T>
) -> RotationMultiplicationMatrix2x2 <T> {
RotationMultiplicationMatrix2x2 (**self - **matrix)
}
}
impl <T : Num + Copy> Mul <RotationMultiplicationMatrix2x2 <T>, RotationMultiplicationMatrix2x2 <T>> for RotationMultiplicationMatrix2x2 <T> {
pub fn mul (
&self,
matrix : &RotationMultiplicationMatrix2x2 <T>
) -> RotationMultiplicationMatrix2x2 <T> {
RotationMultiplicationMatrix2x2 (**self * **matrix)
}
}
impl <T : Num + Quot <T, T> + Copy> Quot <RotationMultiplicationMatrix2x2 <T>, RotationMultiplicationMatrix2x2 <T>> for RotationMultiplicationMatrix2x2 <T> {
pub fn quot (
&self,
matrix : &RotationMultiplicationMatrix2x2 <T>
) -> RotationMultiplicationMatrix2x2 <T> {
RotationMultiplicationMatrix2x2 (**self / **matrix)
}
}
impl <T : Num> One for RotationMultiplicationMatrix2x2 <T> {
pub fn one () -> RotationMultiplicationMatrix2x2 <T> {
RotationMultiplicationMatrix2x2 (One::one ())
}
}
impl <T : Num> Zero for RotationMultiplicationMatrix2x2 <T> {
pub fn zero () -> RotationMultiplicationMatrix2x2 <T> {
RotationMultiplicationMatrix2x2 (Zero::zero ())
}
}
impl <T : Num + Copy> Neg <RotationMultiplicationMatrix2x2 <T>> for RotationMultiplicationMatrix2x2 <T> {
pub fn neg (&self) -> RotationMultiplicationMatrix2x2 <T> {
RotationMultiplicationMatrix2x2 (-**self)
}
}
impl <T> Num for RotationMultiplicationMatrix2x2 <T> {
}
impl <T : Num + Copy> Matrix2x2 <T> {
pub fn apply (self, Vector2 { x, y } : Vector2 <T>) -> Vector2 <T> {
let Vector2 { x, y } = self.rotate (Vector2 {
x : RotationMultiplicationMatrix2x2 (Cmplx { re : x, im : Zero::zero () }),
y : RotationMultiplicationMatrix2x2 (Cmplx { re : y, im : Zero::zero () })
});
Vector2 { x : x.re, y : y.re }
}
}
#[test]
pub fn identity_matrix_works () {
// Use uint arithmetic because floating point is strange
let identity = Matrix2x2::new (
1, 0,
0, 1
);
let test_cases = [
Vector2 { x : 1, y : 0 },
Vector2 { x : 1, y : 1 },
Vector2 { x : 0, y : 1 },
Vector2 { x : 4, y : 5 },
Vector2 { x : 320, y : 50 }
];
for test_cases.each |&test_case| {
let result = identity.apply (test_case);
if result != test_case {
fail! (fmt! (
"The test case %? applied to the identity became %?",
test_case,
result));
}
}
}
#[test]
pub fn other_matrix_works () {
let one : Matrix2x2 <f32> = Zero::zero ();
}
// x = [a, -b], a rotation matrix, or a + ib.
// [b, a]
//
// The matrix inverse of it is therefore [a, b] / (a * a + b * b), or
// [-b, a]
// (a - ib) / (a * a + b * b)
//
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment