[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))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -262,7 +262,7 @@ double Matrix::cofactor(uint8_t a_row, uint8_t a_col) const
|
|||||||
|
|
||||||
bool Matrix::invertible(void) const
|
bool Matrix::invertible(void) const
|
||||||
{
|
{
|
||||||
if (determinant() == 0)
|
if (double_equal(determinant(), 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
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
|
bool Matrix::validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const
|
||||||
{
|
{
|
||||||
for (const auto &the_row : a_values)
|
for (const auto &the_row : a_values)
|
||||||
|
|||||||
@@ -73,6 +73,9 @@ namespace Raytracer
|
|||||||
static Matrix identity(void);
|
static Matrix identity(void);
|
||||||
static Matrix translation(double an_x, double an_y, double an_z);
|
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 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:
|
private:
|
||||||
bool validate_dimensions(const std::initializer_list<std::initializer_list<double>> &a_values) const;
|
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));
|
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