Skip to content

Commit 2968443

Browse files
author
Peter
committed
Associativity issue because w is not multiplied
1 parent d2a14e8 commit 2968443

File tree

2 files changed

+41
-7
lines changed

2 files changed

+41
-7
lines changed

src/matrix4d.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ where T: Copy + Clone +
369369
/// The input point must be use the unit Src, and the returned point has the unit Dst.
370370
#[inline]
371371
pub fn transform_point4d(&self, p: &TypedPoint4D<T, Src>) -> TypedPoint4D<T, Dst> {
372-
let x = p.x * self.m11 + p.y * self.m21 + p.z * self.m31 + self.m41;
373-
let y = p.x * self.m12 + p.y * self.m22 + p.z * self.m32 + self.m42;
374-
let z = p.x * self.m13 + p.y * self.m23 + p.z * self.m33 + self.m43;
375-
let w = p.x * self.m14 + p.y * self.m24 + p.z * self.m34 + self.m44;
372+
let x = p.x * self.m11 + p.y * self.m21 + p.z * self.m31 + p.w * self.m41;
373+
let y = p.x * self.m12 + p.y * self.m22 + p.z * self.m32 + p.w * self.m42;
374+
let z = p.x * self.m13 + p.y * self.m23 + p.z * self.m33 + p.w * self.m43;
375+
let w = p.x * self.m14 + p.y * self.m24 + p.z * self.m34 + p.w * self.m44;
376376
TypedPoint4D::new(x, y, z, w)
377377
}
378378

@@ -553,11 +553,11 @@ impl<T: Copy + fmt::Debug, Src, Dst> fmt::Debug for TypedMatrix4D<T, Src, Dst> {
553553

554554
#[cfg(test)]
555555
mod tests {
556-
use point::{Point2D, Point3D};
556+
use approxeq::ApproxEq;
557557
use matrix2d::Matrix2D;
558+
use point::{Point2D, Point3D, Point4D};
558559
use Radians;
559560
use super::*;
560-
use approxeq::ApproxEq;
561561

562562
use std::f32::consts::FRAC_PI_2;
563563

@@ -743,4 +743,21 @@ mod tests {
743743
assert_eq!(size_of::<Matrix4D<f32>>(), 16*size_of::<f32>());
744744
assert_eq!(size_of::<Matrix4D<f64>>(), 16*size_of::<f64>());
745745
}
746+
747+
#[test]
748+
pub fn test_transform_associativity() {
749+
let m1 = Mf32::row_major(3.0, 2.0, 1.5, 1.0,
750+
0.0, 4.5, -1.0, -4.0,
751+
0.0, 3.5, 2.5, 40.0,
752+
0.0, 3.0, 0.0, 1.0);
753+
let m2 = Mf32::row_major(1.0, -1.0, 3.0, 0.0,
754+
-1.0, 0.5, 0.0, 2.0,
755+
1.5, -2.0, 6.0, 0.0,
756+
-2.5, 6.0, 1.0, 1.0);
757+
758+
let p = Point4D::new(1.0, 3.0, 5.0, 1.0);
759+
let p1 = m2.pre_mul(&m1).transform_point4d(&p);
760+
let p2 = m2.transform_point4d(&m1.transform_point4d(&p));
761+
assert!(p1.approx_eq(&p2));
762+
}
746763
}

src/point.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
// except according to those terms.
99

1010
use super::UnknownUnit;
11+
use approxeq::ApproxEq;
1112
use length::Length;
1213
use scale_factor::ScaleFactor;
1314
use size::TypedSize2D;
1415
use num::*;
15-
use approxeq::ApproxEq;
1616
use num_traits::{Float, NumCast};
1717
use std::fmt;
1818
use std::ops::{Add, Neg, Mul, Sub, Div};
@@ -731,6 +731,23 @@ impl<T: NumCast + Copy, U> TypedPoint4D<T, U> {
731731
}
732732
}
733733

734+
impl<T: ApproxEq<T>, U> ApproxEq<T> for TypedPoint4D<T, U> {
735+
fn approx_epsilon() -> T {
736+
T::approx_epsilon()
737+
}
738+
739+
fn approx_eq_eps(&self, other: &Self, approx_epsilon: &T) -> bool {
740+
self.x.approx_eq_eps(&other.x, approx_epsilon)
741+
&& self.y.approx_eq_eps(&other.y, approx_epsilon)
742+
&& self.z.approx_eq_eps(&other.z, approx_epsilon)
743+
&& self.w.approx_eq_eps(&other.w, approx_epsilon)
744+
}
745+
746+
fn approx_eq(&self, other: &Self) -> bool {
747+
self.approx_eq_eps(&other, &Self::approx_epsilon())
748+
}
749+
}
750+
734751
#[cfg(test)]
735752
mod point2d {
736753
use super::Point2D;

0 commit comments

Comments
 (0)