Add viewTransform transformation

This commit is contained in:
Godzil
2020-02-20 15:11:40 +00:00
parent 863bb2a34b
commit bc047cd89e
3 changed files with 74 additions and 1 deletions

View File

@@ -21,4 +21,6 @@ Matrix rotationZ(double angle);
Matrix shearing(double Xy, double Xx, double Yx, double Yz, double Zx, double Zy); Matrix shearing(double Xy, double Xx, double Yx, double Yz, double Zx, double Zy);
Matrix viewTransform(Tuple from, Tuple to, Tuple up);
#endif /* DORAYME_TRANSFORMATION_H */ #endif /* DORAYME_TRANSFORMATION_H */

View File

@@ -82,3 +82,18 @@ Matrix shearing(double Xy, double Xz, double Yx, double Yz, double Zx, double Zy
return ret; return ret;
} }
Matrix viewTransform(Tuple from, Tuple to, Tuple up)
{
Tuple forward = (to - from).normalise();
Tuple left = forward.cross(up.normalise());
Tuple true_up = left.cross(forward);
double orientationValues[] = { left.x, left.y, left.z, 0,
true_up.x, true_up.y, true_up.z, 0,
-forward.x, -forward.y, -forward.z, 0,
0, 0, 0, 1 };
Matrix orientation = Matrix4(orientationValues);
return orientation * translation(-from.x, -from.y, -from.z);
}

View File

@@ -190,6 +190,61 @@ TEST(TransformationTest, Chained_transformation_must_be_applied_in_reverse_order
ASSERT_EQ(T * p, Point(15, 0, 7)); ASSERT_EQ(T * p, Point(15, 0, 7));
} }
TEST(TransformationTest, The_transformation_matrix_for_the_default_orientation)
{
Tuple from = Point(0, 0, 0);
Tuple to = Point(0, 0, -1);
Tuple up = Vector(0, 1, 0);
Matrix t = viewTransform(from, to, up);
ASSERT_EQ(t, Matrix4().identity());
}
TEST(TransformationTest, A_view_transformation_matrix_looking_in_positive_z_direction)
{
Tuple from = Point(0, 0, 0);
Tuple to = Point(0, 0, 1);
Tuple up = Vector(0, 1, 0);
Matrix t = viewTransform(from, to, up);
ASSERT_EQ(t, scaling(-1, 1, -1));
}
TEST(TransformationTest, The_view_transformation_move_the_world)
{
Tuple from = Point(0, 0, 8);
Tuple to = Point(0, 0, 0);
Tuple up = Vector(0, 1, 0);
Matrix t = viewTransform(from, to, up);
ASSERT_EQ(t, translation(0, 0, -8));
}
TEST(TransformationTest, An_arbitrary_view_transformation)
{
Tuple from = Point(1, 3, 2);
Tuple to = Point(4, -2, 8);
Tuple up = Vector(1, 1, 0);
Matrix t = viewTransform(from, to, up);
double values[] = {-0.50709, 0.50709, 0.67612, -2.36643,
0.76772, 0.60609, 0.12122, -2.82843,
-0.35857, 0.59761, -0.71714, 0.00000,
0.00000, 0.00000, 0.00000, 1.00000};
/* Temporary lower the precision */
set_equal_precision(0.00001);
ASSERT_EQ(t, Matrix4(values));
set_equal_precision(FLT_EPSILON);
}
TEST(TransformationTest, Check_that_deg_to_rad_is_working) TEST(TransformationTest, Check_that_deg_to_rad_is_working)
{ {
double angle180 = deg_to_rad(180); double angle180 = deg_to_rad(180);
@@ -200,3 +255,4 @@ TEST(TransformationTest, Check_that_deg_to_rad_is_working)
ASSERT_EQ(angle90, M_PI / 2.); ASSERT_EQ(angle90, M_PI / 2.);
ASSERT_EQ(angle270, M_PI * 1.5); ASSERT_EQ(angle270, M_PI * 1.5);
} }