[FEAT] Add Transformation Rotation
This commit is contained in:
@@ -120,7 +120,7 @@ bool Matrix::operator==(const Matrix &a_matrix) const
|
||||
{
|
||||
if (!double_equal(*the_elem1, *the_elem2))
|
||||
{
|
||||
printf("Elem: %f != %f\n", *the_elem1, *the_elem2);
|
||||
// printf("Elem: %f != %f\n", *the_elem1, *the_elem2);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -262,7 +262,7 @@ double Matrix::cofactor(uint8_t a_row, uint8_t a_col) const
|
||||
|
||||
bool Matrix::invertible(void) const
|
||||
{
|
||||
if (determinant() == 0)
|
||||
if (double_equal(determinant(), 0))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -340,6 +340,48 @@ Matrix Matrix::scaling(double an_x, double an_y, double an_z)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Matrix Matrix::rotation_x(double a_radians)
|
||||
{
|
||||
Matrix the_rotation = {
|
||||
{1, 0, 0, 0},
|
||||
{0, cos(a_radians), -sin(a_radians), 0},
|
||||
{0, sin(a_radians), cos(a_radians), 0},
|
||||
{0, 0, 0, 1}
|
||||
};
|
||||
|
||||
return the_rotation;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Matrix Matrix::rotation_y(double a_radians)
|
||||
{
|
||||
Matrix the_rotation = {
|
||||
{ cos(a_radians), 0, sin(a_radians), 0},
|
||||
{ 0, 1, 0, 0},
|
||||
{-sin(a_radians), 0, cos(a_radians), 0},
|
||||
{ 0, 0, 0, 1}
|
||||
};
|
||||
|
||||
return the_rotation;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Matrix Matrix::rotation_z(double a_radians)
|
||||
{
|
||||
Matrix the_rotation = {
|
||||
{cos(a_radians), -sin(a_radians), 0, 0},
|
||||
{sin(a_radians), cos(a_radians), 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1}
|
||||
};
|
||||
|
||||
return the_rotation;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool Matrix::validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const
|
||||
{
|
||||
for (const auto &the_row : a_values)
|
||||
|
||||
@@ -73,6 +73,9 @@ namespace Raytracer
|
||||
static Matrix identity(void);
|
||||
static Matrix translation(double an_x, double an_y, double an_z);
|
||||
static Matrix scaling(double an_x, double an_y, double an_z);
|
||||
static Matrix rotation_x(double a_radians);
|
||||
static Matrix rotation_y(double a_radians);
|
||||
static Matrix rotation_z(double a_radians);
|
||||
|
||||
private:
|
||||
bool validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const;
|
||||
|
||||
@@ -102,3 +102,52 @@ TEST_CASE("[04][TRANSFORMATION] Reflection is scaling by a negative value", "[Ma
|
||||
|
||||
REQUIRE(transform * p == Tuple::Point(-2, 3, 4));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][TRANSFORMATION] Rotating a point around the x axis", "[Matrix]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
Matrix half_quarter = Matrix::rotation_x(std::numbers::pi / 4);
|
||||
Matrix full_quarter = Matrix::rotation_x(std::numbers::pi / 2);
|
||||
|
||||
REQUIRE(half_quarter * p == Tuple::Point(0, sqrt(2) / 2, sqrt(2) / 2));
|
||||
REQUIRE(full_quarter * p == Tuple::Point(0, 0, 1));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][TRANSFORMATION] The inverse of an x-rotation rotates in the opposite direction", "[Matrix]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
Matrix half_quarter = Matrix::rotation_x(std::numbers::pi / 4);
|
||||
Matrix inv = half_quarter.inverse();
|
||||
|
||||
REQUIRE(inv * p == Tuple::Point(0, sqrt(2) / 2, -sqrt(2) / 2));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][TRANSFORMATION] Rotating a point around the y axis", "[Matrix]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 0, 1);
|
||||
Matrix half_quarter = Matrix::rotation_y(std::numbers::pi / 4);
|
||||
Matrix full_quarter = Matrix::rotation_y(std::numbers::pi / 2);
|
||||
|
||||
REQUIRE(half_quarter * p == Tuple::Point(sqrt(2) / 2, 0, sqrt(2) / 2));
|
||||
REQUIRE(full_quarter * p == Tuple::Point(1, 0, 0));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[04][TRANSFORMATION] Rotating a point around the z axis", "[Matrix]")
|
||||
{
|
||||
Tuple p = Tuple::Point(0, 1, 0);
|
||||
Matrix half_quarter = Matrix::rotation_z(std::numbers::pi / 4);
|
||||
Matrix full_quarter = Matrix::rotation_z(std::numbers::pi / 2);
|
||||
|
||||
Tuple z = half_quarter * p;
|
||||
|
||||
REQUIRE(half_quarter * p == Tuple::Point(-sqrt(2) / 2, sqrt(2) / 2, 0));
|
||||
REQUIRE(full_quarter * p == Tuple::Point(-1, 0, 0));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user