[FEAT] Add normalize
This commit is contained in:
@@ -34,13 +34,25 @@
|
||||
#include "tuple.h"
|
||||
|
||||
#define kEpsilon 0.00001
|
||||
#define square(a) (a)*(a)
|
||||
#define square(a) (a) * (a)
|
||||
|
||||
using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Tuple::Tuple(float a_x, float a_y, float a_z, float a_w) : m_x(a_x), m_y(a_y), m_z(a_z), m_w(a_w)
|
||||
Tuple::Tuple(void) : m_x(0.0), m_y(0.0), m_z(0.0), m_w(0.0)
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Tuple::Tuple(const Tuple &a_copy) : m_x(a_copy.m_x), m_y(a_copy.m_y), m_z(a_copy.m_z), m_w(a_copy.m_w)
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Tuple::Tuple(double a_x, double a_y, double a_z, double a_w) : m_x(a_x), m_y(a_y), m_z(a_z), m_w(a_w)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -48,7 +60,7 @@ Tuple::Tuple(float a_x, float a_y, float a_z, float a_w) : m_x(a_x), m_y(a_y), m
|
||||
|
||||
bool Tuple::operator==(const Tuple &an_other) const
|
||||
{
|
||||
if (float_equal(m_x, an_other.m_x) && float_equal(m_y, an_other.m_y) && float_equal(m_z, an_other.m_z) && float_equal(m_w, an_other.m_w))
|
||||
if (double_equal(m_x, an_other.m_x) && double_equal(m_y, an_other.m_y) && double_equal(m_z, an_other.m_z) && double_equal(m_w, an_other.m_w))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -94,7 +106,7 @@ const Tuple &Tuple::operator-(void)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
const Tuple &Tuple::operator*(float a_scalar)
|
||||
const Tuple &Tuple::operator*(double a_scalar)
|
||||
{
|
||||
m_x *= a_scalar;
|
||||
m_y *= a_scalar;
|
||||
@@ -106,7 +118,7 @@ const Tuple &Tuple::operator*(float a_scalar)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
const Tuple &Tuple::operator/(float a_scalar)
|
||||
const Tuple &Tuple::operator/(double a_scalar)
|
||||
{
|
||||
m_x /= a_scalar;
|
||||
m_y /= a_scalar;
|
||||
@@ -118,42 +130,42 @@ const Tuple &Tuple::operator/(float a_scalar)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Tuple Tuple::Point(float an_x, float an_y, float an_z)
|
||||
Tuple Tuple::Point(double an_x, double an_y, double an_z)
|
||||
{
|
||||
return Tuple(an_x, an_y, an_z, kRaytracerTuplePoint);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Tuple Tuple::Vector(float an_x, float an_y, float an_z)
|
||||
Tuple Tuple::Vector(double an_x, double an_y, double an_z)
|
||||
{
|
||||
return Tuple(an_x, an_y, an_z, kRaytracerTupleVector);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
float Tuple::x(void) const
|
||||
double Tuple::x(void) const
|
||||
{
|
||||
return m_x;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
float Tuple::y(void) const
|
||||
double Tuple::y(void) const
|
||||
{
|
||||
return m_y;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
float Tuple::z(void) const
|
||||
double Tuple::z(void) const
|
||||
{
|
||||
return m_z;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
float Tuple::w(void) const
|
||||
double Tuple::w(void) const
|
||||
{
|
||||
return m_w;
|
||||
}
|
||||
@@ -162,29 +174,39 @@ float Tuple::w(void) const
|
||||
|
||||
bool Tuple::is_point(void)
|
||||
{
|
||||
return float_equal(m_w, kRaytracerTuplePoint);
|
||||
return double_equal(m_w, kRaytracerTuplePoint);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool Tuple::is_vector(void)
|
||||
{
|
||||
return float_equal(m_w, kRaytracerTupleVector);
|
||||
return double_equal(m_w, kRaytracerTupleVector);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
float Tuple::magnitude(void)
|
||||
double Tuple::magnitude(void) const
|
||||
{
|
||||
return sqrtf(
|
||||
square(m_x) + square(m_y) + square(m_z) + square(m_w)
|
||||
);
|
||||
|
||||
return std::sqrt(
|
||||
square(m_x) + square(m_y) + square(m_z) + square(m_w));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool Tuple::float_equal(float a, float b) const
|
||||
Tuple Tuple::normalize(void)
|
||||
{
|
||||
double the_magnitude = magnitude();
|
||||
|
||||
return Tuple(m_x / the_magnitude,
|
||||
m_y / the_magnitude,
|
||||
m_z / the_magnitude,
|
||||
m_w / the_magnitude);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
bool Tuple::double_equal(double a, double b) const
|
||||
{
|
||||
if ((std::abs((a) - (b)) < kEpsilon))
|
||||
{
|
||||
|
||||
@@ -38,37 +38,40 @@ namespace Raytracer
|
||||
class Tuple
|
||||
{
|
||||
public:
|
||||
Tuple(float an_x, float an_y, float an_z, float an_w);
|
||||
Tuple(void);
|
||||
Tuple(const Tuple &a_copy);
|
||||
Tuple(double an_x, double an_y, double an_z, double an_w);
|
||||
|
||||
bool operator==(const Tuple &an_other) const;
|
||||
const Tuple &operator+(const Tuple &an_other);
|
||||
const Tuple &operator-(const Tuple &an_other);
|
||||
const Tuple &operator-(void);
|
||||
const Tuple &operator*(float a_scalar);
|
||||
const Tuple &operator/(float a_scalar);
|
||||
const Tuple &operator*(double a_scalar);
|
||||
const Tuple &operator/(double a_scalar);
|
||||
|
||||
static Tuple Point(float an_x, float an_y, float an_z);
|
||||
static Tuple Vector(float an_x, float an_y, float an_z);
|
||||
static Tuple Point(double an_x, double an_y, double an_z);
|
||||
static Tuple Vector(double an_x, double an_y, double an_z);
|
||||
|
||||
// Access
|
||||
float x(void) const;
|
||||
float y(void) const;
|
||||
float z(void) const;
|
||||
float w(void) const;
|
||||
double x(void) const;
|
||||
double y(void) const;
|
||||
double z(void) const;
|
||||
double w(void) const;
|
||||
|
||||
bool is_point(void);
|
||||
bool is_vector(void);
|
||||
|
||||
float magnitude(void);
|
||||
double magnitude(void) const;
|
||||
Tuple normalize(void);
|
||||
|
||||
protected:
|
||||
float m_x;
|
||||
float m_y;
|
||||
float m_z;
|
||||
float m_w;
|
||||
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
double m_w;
|
||||
|
||||
private:
|
||||
bool float_equal(float a, float b) const;
|
||||
bool double_equal(double a, double b) const;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
@@ -39,10 +39,10 @@ TEST_CASE("a tuple with w=1.0 is a point", "[Tuple]")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 1.0);
|
||||
|
||||
REQUIRE(a.x() == 4.3f);
|
||||
REQUIRE(a.y() == -4.2f);
|
||||
REQUIRE(a.z() == 3.1f);
|
||||
REQUIRE(a.w() == 1.0f);
|
||||
REQUIRE(a.x() == 4.3);
|
||||
REQUIRE(a.y() == -4.2);
|
||||
REQUIRE(a.z() == 3.1);
|
||||
REQUIRE(a.w() == 1.0);
|
||||
|
||||
REQUIRE(a.is_point() == true);
|
||||
REQUIRE(a.is_vector() == false);
|
||||
@@ -54,10 +54,10 @@ TEST_CASE("a tuple with w=0 is a vector", "[Tuple]")
|
||||
{
|
||||
Tuple a(4.3, -4.2, 3.1, 0.0);
|
||||
|
||||
REQUIRE(a.x() == 4.3f);
|
||||
REQUIRE(a.y() == -4.2f);
|
||||
REQUIRE(a.z() == 3.1f);
|
||||
REQUIRE(a.w() == 0.0f);
|
||||
REQUIRE(a.x() == 4.3);
|
||||
REQUIRE(a.y() == -4.2);
|
||||
REQUIRE(a.z() == 3.1);
|
||||
REQUIRE(a.w() == 0.0);
|
||||
|
||||
REQUIRE(a.is_point() == false);
|
||||
}
|
||||
@@ -105,7 +105,7 @@ TEST_CASE("Subtracting two points", "[Tuple][Operations]")
|
||||
TEST_CASE("Subtracting a vector from a point", "[Tuple][Operations]")
|
||||
{
|
||||
Tuple p = Tuple::Point(3, 2, 1);
|
||||
Tuple v= Tuple::Vector(5, 6, 7);
|
||||
Tuple v = Tuple::Vector(5, 6, 7);
|
||||
|
||||
REQUIRE((p - v) == Tuple::Point(-2, -4, -6));
|
||||
}
|
||||
@@ -190,7 +190,7 @@ TEST_CASE("Computing the magnitude of vector(1,2,3)", "[Tuple][Magnitude]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
|
||||
REQUIRE(v.magnitude() == sqrtf(14));
|
||||
REQUIRE(v.magnitude() == sqrt(14));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -199,5 +199,35 @@ TEST_CASE("Computing the magnitude of vector(-1,-2,-3)", "[Tuple][Magnitude]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(-1, -2, -3);
|
||||
|
||||
REQUIRE(v.magnitude() == sqrtf(14));
|
||||
REQUIRE(v.magnitude() == sqrt(14));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("Normalize vector(4,0,0) gives (1,0,0)", "[Tuple][Normalize]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(4, 0, 0);
|
||||
|
||||
REQUIRE(v.normalize() == Tuple::Vector(1, 0, 0));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("Normalize vector(1,2,3)", "[Tuple][Normalize]")
|
||||
{
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
|
||||
REQUIRE(v.normalize() == Tuple::Vector(1 / sqrtf(14), 2 / sqrtf(14), 3 / sqrtf(14)));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("The magnitude of a normalized vector", "[Tuple][Normalize]")
|
||||
{
|
||||
Tuple norm;
|
||||
Tuple v = Tuple::Vector(1, 2, 3);
|
||||
|
||||
norm = v.normalize();
|
||||
|
||||
REQUIRE(norm.magnitude() == 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user