[FEAT] Add Normal
This commit is contained in:
@@ -65,7 +65,8 @@ Matrix::Matrix(const Matrix &an_other) : m_rows(an_other.m_rows), m_cols(an_othe
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Matrix::Matrix(const std::initializer_list<std::initializer_list<double>> &a_values) :
|
||||
m_rows(a_values.size()), m_cols(a_values.size())
|
||||
m_rows(a_values.size()),
|
||||
m_cols(a_values.size())
|
||||
{
|
||||
m_data = std::vector<std::vector<double>>(m_rows, std::vector<double>(m_cols));
|
||||
if (!validate_dimensions(a_values))
|
||||
@@ -187,19 +188,19 @@ Matrix &Matrix::operator=(const Matrix &a_matrix)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool Matrix::transpose(void)
|
||||
Matrix Matrix::transpose(void)
|
||||
{
|
||||
std::vector<std::vector<double>> the_copy = m_data;
|
||||
Matrix the_transposed(m_rows, m_cols);
|
||||
|
||||
for (int the_row = 0; the_row < m_rows; the_row++)
|
||||
{
|
||||
for (int the_col = 0; the_col < m_cols; the_col++)
|
||||
{
|
||||
m_data[the_col][the_row] = the_copy[the_row][the_col];
|
||||
the_transposed[the_col][the_row] = m_data[the_row][the_col];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return the_transposed;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Raytracer
|
||||
|
||||
Matrix &operator=(const Matrix &a_matrix);
|
||||
|
||||
bool transpose(void);
|
||||
Matrix transpose(void);
|
||||
double determinant(void) const;
|
||||
Matrix sub_matrix(uint8_t a_row, uint8_t a_col) const;
|
||||
double minor(uint8_t a_row, uint8_t a_col) const;
|
||||
|
||||
@@ -96,10 +96,13 @@ void Shape::set_transform(const Matrix &a_transform_matrix)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Tuple Shape::normal_at(const Tuple &a_point)
|
||||
Tuple Shape::normal_at(const Tuple &a_world_point)
|
||||
{
|
||||
Tuple the_result = a_point - Tuple::Point(0, 0, 0);
|
||||
return the_result.normalize();
|
||||
Tuple the_object_point = m_transform.inverse() * a_world_point;
|
||||
Tuple the_object_normal = the_object_point - Tuple::Point(0, 0, 0);
|
||||
Tuple the_world_normal = m_transform.inverse().transpose() * the_object_normal;
|
||||
the_world_normal.set_w(0);
|
||||
return the_world_normal.normalize();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
@@ -258,6 +258,34 @@ double Tuple::w(void) const
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void Tuple::set_x(double an_x)
|
||||
{
|
||||
m_x = an_x;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void Tuple::set_y(double an_y)
|
||||
{
|
||||
m_y = an_y;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void Tuple::set_z(double a_z)
|
||||
{
|
||||
m_z = a_z;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void Tuple::set_w(double a_w)
|
||||
{
|
||||
m_w = a_w;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool Tuple::is_point(void)
|
||||
{
|
||||
return double_equal(m_w, kRaytracerTuplePoint);
|
||||
|
||||
@@ -73,6 +73,11 @@ namespace Raytracer
|
||||
double z(void) const;
|
||||
double w(void) const;
|
||||
|
||||
void set_x(double an_x);
|
||||
void set_y(double an_y);
|
||||
void set_z(double a_z);
|
||||
void set_w(double a_w);
|
||||
|
||||
bool is_point(void);
|
||||
bool is_vector(void);
|
||||
|
||||
|
||||
@@ -324,9 +324,7 @@ SCENARIO("Transposing a matrix", "[features/matrices.feature]")
|
||||
{0, 8, 3, 8}
|
||||
};
|
||||
|
||||
A.transpose();
|
||||
|
||||
REQUIRE(A == transposed);
|
||||
REQUIRE(A.transpose() == transposed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -337,9 +335,8 @@ SCENARIO("Transposing the identity matrix", "[features/matrices.feature]")
|
||||
{
|
||||
GIVEN("A <- transpose(identity_matrix)")
|
||||
{
|
||||
Matrix A = Matrix::identity();
|
||||
Matrix A = Matrix::identity().transpose();
|
||||
|
||||
A.transpose();
|
||||
THEN("A = identity_matrix")
|
||||
{
|
||||
REQUIRE(A == Matrix::identity());
|
||||
|
||||
@@ -120,3 +120,51 @@ SCENARIO("The normal is a normalized vector", "[features/spheres.feature]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
SCENARIO("Computing the normal on a translated sphere", "[features/spheres.feature]")
|
||||
{
|
||||
GIVEN("s <- sphere()")
|
||||
{
|
||||
Sphere s;
|
||||
AND_GIVEN("set_transform(s, translation(0,1,0))")
|
||||
{
|
||||
s.set_transform(Matrix::translation(0, 1, 0));
|
||||
WHEN("n <- normal_at(s,point(0,1.70711,-0.70711))")
|
||||
{
|
||||
Tuple n = s.normal_at(Tuple::Point(0, 1.70711, -0.70711));
|
||||
THEN("n = vector(0,0.70711, -0.70711)")
|
||||
{
|
||||
REQUIRE(n == Tuple::Vector(0, 0.70711, -0.70711));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
SCENARIO("Computing the normal on a transformed sphere", "[features/spheres.feature]")
|
||||
{
|
||||
GIVEN("s <- sphere()")
|
||||
{
|
||||
Sphere s;
|
||||
AND_GIVEN("m <- scaling(1,0.5,1) * rotation_z(pi/5)")
|
||||
{
|
||||
Matrix m = Matrix::scaling(1, 0.5, 1) * Matrix::rotation_z(std::numbers::pi / 5);
|
||||
AND_GIVEN("set_transform(s, m)")
|
||||
{
|
||||
s.set_transform(m);
|
||||
WHEN("n <- normal_at(s,point(0,sqrt(2)/2,sqrt(2)/2))")
|
||||
{
|
||||
Tuple n = s.normal_at(Tuple::Point(0, sqrt(2) / 2, -sqrt(2) / 2));
|
||||
THEN("n = vector(0,97014, -0.24254)")
|
||||
{
|
||||
REQUIRE(n == Tuple::Vector(0, 0.97014, -0.24254));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user