[FEAT] Add a new intersections objects
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
[](https://drone.nadal-fr.com/raytracing/raytracing_challenge)
|
||||||
|
|
||||||
## Le Livre est ici:
|
## Le Livre est ici:
|
||||||
|
|
||||||
https://lire.amazon.fr/?asin=B07Q84TQ91&ref_=kwl_kr_iv_rec_1
|
https://lire.amazon.fr/?asin=B07Q84TQ91&ref_=kwl_kr_iv_rec_1
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ add_library(raytracing
|
|||||||
src/common.cpp
|
src/common.cpp
|
||||||
src/color.cpp
|
src/color.cpp
|
||||||
src/intersection.cpp
|
src/intersection.cpp
|
||||||
|
src/intersections.cpp
|
||||||
src/matrix.cpp
|
src/matrix.cpp
|
||||||
src/object.cpp
|
src/object.cpp
|
||||||
src/ray.cpp
|
src/ray.cpp
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "intersection.h"
|
#include "intersection.h"
|
||||||
|
#include "intersections.h"
|
||||||
#include "matrix.h"
|
#include "matrix.h"
|
||||||
#include "ray.h"
|
#include "ray.h"
|
||||||
#include "sphere.h"
|
#include "sphere.h"
|
||||||
|
|||||||
@@ -34,12 +34,41 @@ using namespace Raytracer;
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Intersection::Intersection(void) : m_distance_t(0.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Intersection::Intersection(double a_distance_t, Object an_object) : m_distance_t(a_distance_t), m_object(an_object)
|
Intersection::Intersection(double a_distance_t, Object an_object) : m_distance_t(a_distance_t), m_object(an_object)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Intersection::Intersection(Intersection &an_intersection) :
|
||||||
|
m_distance_t(an_intersection.m_distance_t),
|
||||||
|
m_object(an_intersection.m_object)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
const Intersection &Intersection::operator=(const Intersection &an_intersection)
|
||||||
|
{
|
||||||
|
if (this == &an_intersection)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_distance_t = an_intersection.m_distance_t;
|
||||||
|
m_object = an_intersection.m_object;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
double Intersection::distance_t(void)
|
double Intersection::distance_t(void)
|
||||||
{
|
{
|
||||||
return m_distance_t;
|
return m_distance_t;
|
||||||
|
|||||||
@@ -37,7 +37,11 @@ namespace Raytracer
|
|||||||
class Intersection
|
class Intersection
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Intersection(void);
|
||||||
Intersection(double a_distance_t, Object an_object);
|
Intersection(double a_distance_t, Object an_object);
|
||||||
|
Intersection(Intersection &an_intersection);
|
||||||
|
|
||||||
|
const Intersection &operator=(const Intersection &an_intersection);
|
||||||
|
|
||||||
double distance_t(void);
|
double distance_t(void);
|
||||||
Object &object(void);
|
Object &object(void);
|
||||||
|
|||||||
107
raytracing/src/intersections.cpp
Normal file
107
raytracing/src/intersections.cpp
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*!
|
||||||
|
* intersections.cpp
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* @Author: NADAL Jean-Baptiste
|
||||||
|
* @Date: 12/02/2024
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
|
||||||
|
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "intersections.h"
|
||||||
|
|
||||||
|
using namespace Raytracer;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Intersections::Intersections(void) : m_count(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Intersections::Intersections(const Intersection &an_intersection1, const Intersection &an_intersection2)
|
||||||
|
{
|
||||||
|
m_array[0] = an_intersection1;
|
||||||
|
m_array[1] = an_intersection2;
|
||||||
|
m_count = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Intersections::Intersections(Intersection &an_intersection1, Intersection &an_intersection2)
|
||||||
|
{
|
||||||
|
m_array[0] = an_intersection1;
|
||||||
|
m_array[1] = an_intersection2;
|
||||||
|
m_count = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Intersections::Intersections(Intersections &an_other)
|
||||||
|
{
|
||||||
|
m_array[0] = an_other.m_array[0];
|
||||||
|
m_array[1] = an_other.m_array[1];
|
||||||
|
m_count = an_other.m_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
Intersection &Intersections::operator[](uint8_t an_index)
|
||||||
|
{
|
||||||
|
return m_array[an_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
const Intersections &Intersections::operator=(const Intersections &an_other)
|
||||||
|
{
|
||||||
|
if (this == &an_other)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_array[0] = an_other.m_array[0];
|
||||||
|
m_array[1] = an_other.m_array[1];
|
||||||
|
m_count = an_other.m_count;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
bool Intersections::set(Intersection an_intersection1, Intersection an_intersection2)
|
||||||
|
{
|
||||||
|
m_array[0] = an_intersection1;
|
||||||
|
m_array[1] = an_intersection2;
|
||||||
|
m_count = 2;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
uint8_t Intersections::count(void) const
|
||||||
|
{
|
||||||
|
return m_count;
|
||||||
|
}
|
||||||
60
raytracing/src/intersections.h
Normal file
60
raytracing/src/intersections.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*!
|
||||||
|
* intersections.h
|
||||||
|
*
|
||||||
|
* Copyright (c) 2024, NADAL Jean-Baptiste. All rights reserved.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
* @Author: NADAL Jean-Baptiste
|
||||||
|
* @Date: 12/02/2024
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _RAYTRACER_INTERSECTIONS_H
|
||||||
|
#define _RAYTRACER_INTERSECTIONS_H
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "intersection.h"
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
namespace Raytracer
|
||||||
|
{
|
||||||
|
class Intersections
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Intersections(void);
|
||||||
|
Intersections(const Intersection &an_intersection1, const Intersection &an_intersection2);
|
||||||
|
Intersections(Intersection &an_intersection1, Intersection &an_intersection2);
|
||||||
|
Intersections(Intersections &an_intersections);
|
||||||
|
|
||||||
|
Intersection &operator[](uint8_t an_index);
|
||||||
|
const Intersections &operator=(const Intersections &an_other);
|
||||||
|
|
||||||
|
bool set(Intersection an_intersection1, Intersection an_intersection2);
|
||||||
|
|
||||||
|
uint8_t count(void) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t m_count;
|
||||||
|
Intersection m_array[2];
|
||||||
|
};
|
||||||
|
}; // namespace Raytracer
|
||||||
|
|
||||||
|
#endif // _RAYTRACER_INTERSECTION_H
|
||||||
@@ -64,9 +64,9 @@ Tuple Ray::position(double a_distance)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
std::vector<double> Ray::intersect(Sphere a_sphere)
|
Intersections Ray::intersect(Sphere a_sphere)
|
||||||
{
|
{
|
||||||
std::vector<double> the_result;
|
Intersections the_intersections;
|
||||||
Tuple the_sphere_to_ray = m_origin - Tuple::Point(0, 0, 0);
|
Tuple the_sphere_to_ray = m_origin - Tuple::Point(0, 0, 0);
|
||||||
|
|
||||||
double the_a = m_direction.dot(m_direction);
|
double the_a = m_direction.dot(m_direction);
|
||||||
@@ -74,13 +74,15 @@ std::vector<double> Ray::intersect(Sphere a_sphere)
|
|||||||
double the_c = the_sphere_to_ray.dot(the_sphere_to_ray) - 1;
|
double the_c = the_sphere_to_ray.dot(the_sphere_to_ray) - 1;
|
||||||
|
|
||||||
double discriminant = std::pow(the_b, 2) - 4 * the_a * the_c;
|
double discriminant = std::pow(the_b, 2) - 4 * the_a * the_c;
|
||||||
|
double the_sqrt = std::sqrt(discriminant);
|
||||||
|
|
||||||
if (discriminant >= 0)
|
if (discriminant >= 0)
|
||||||
{
|
{
|
||||||
the_result.resize(2);
|
the_intersections.set(Intersection((-the_b - the_sqrt) / (2 * the_a), a_sphere),
|
||||||
the_result[0] = (-the_b - std::sqrt(discriminant)) / (2 * the_a);
|
Intersection((-the_b + the_sqrt) / (2 * the_a), a_sphere)
|
||||||
the_result[1] = (-the_b + std::sqrt(discriminant)) / (2 * the_a);
|
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return the_result;
|
return the_intersections;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "intersections.h"
|
||||||
#include "sphere.h"
|
#include "sphere.h"
|
||||||
#include "tuple.h"
|
#include "tuple.h"
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ namespace Raytracer
|
|||||||
const Tuple &direction(void) const;
|
const Tuple &direction(void) const;
|
||||||
|
|
||||||
Tuple position(double a_distance);
|
Tuple position(double a_distance);
|
||||||
std::vector<double> intersect(Sphere a_sphere);
|
Intersections intersect(Sphere a_sphere);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Tuple m_origin;
|
Tuple m_origin;
|
||||||
|
|||||||
@@ -63,11 +63,11 @@ TEST_CASE("[05][Rays] a ray intersects a sphere at two points", "[Sphere]")
|
|||||||
{
|
{
|
||||||
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
||||||
Sphere s;
|
Sphere s;
|
||||||
auto xs = r.intersect(s);
|
Intersections xs = r.intersect(s);
|
||||||
|
|
||||||
REQUIRE(xs.size() == 2);
|
REQUIRE(xs.count() == 2);
|
||||||
REQUIRE(xs[0] == 4.0);
|
REQUIRE(xs[0].distance_t() == 4.0);
|
||||||
REQUIRE(xs[1] == 6.0);
|
REQUIRE(xs[1].distance_t() == 6.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@@ -76,11 +76,11 @@ TEST_CASE("[05][Rays] a ray intersects a sphere at a tangent", "[Sphere]")
|
|||||||
{
|
{
|
||||||
Ray r(Tuple::Point(0, 1, -5), Tuple::Vector(0, 0, 1));
|
Ray r(Tuple::Point(0, 1, -5), Tuple::Vector(0, 0, 1));
|
||||||
Sphere s;
|
Sphere s;
|
||||||
auto xs = r.intersect(s);
|
Intersections xs = r.intersect(s);
|
||||||
|
|
||||||
REQUIRE(xs.size() == 2);
|
REQUIRE(xs.count() == 2);
|
||||||
REQUIRE(xs[0] == 5.0);
|
REQUIRE(xs[0].distance_t() == 5.0);
|
||||||
REQUIRE(xs[1] == 5.0);
|
REQUIRE(xs[1].distance_t() == 5.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@@ -89,9 +89,9 @@ TEST_CASE("[05][Rays] a ray misses a sphere", "[Sphere]")
|
|||||||
{
|
{
|
||||||
Ray r(Tuple::Point(0, 2, -5), Tuple::Vector(0, 0, 1));
|
Ray r(Tuple::Point(0, 2, -5), Tuple::Vector(0, 0, 1));
|
||||||
Sphere s;
|
Sphere s;
|
||||||
auto xs = r.intersect(s);
|
Intersections xs = r.intersect(s);
|
||||||
|
|
||||||
REQUIRE(xs.size() == 0);
|
REQUIRE(xs.count() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@@ -100,11 +100,11 @@ TEST_CASE("[05][Rays] a originates inside a sphere", "[Sphere]")
|
|||||||
{
|
{
|
||||||
Ray r(Tuple::Point(0, 0, 0), Tuple::Vector(0, 0, 1));
|
Ray r(Tuple::Point(0, 0, 0), Tuple::Vector(0, 0, 1));
|
||||||
Sphere s;
|
Sphere s;
|
||||||
auto xs = r.intersect(s);
|
Intersections xs = r.intersect(s);
|
||||||
|
|
||||||
REQUIRE(xs.size() == 2);
|
REQUIRE(xs.count() == 2);
|
||||||
REQUIRE(xs[0] == -1.0);
|
REQUIRE(xs[0].distance_t() == -1.0);
|
||||||
REQUIRE(xs[1] == 1.0);
|
REQUIRE(xs[1].distance_t() == 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@@ -113,11 +113,11 @@ TEST_CASE("[05][Rays] a sphere is behind a ray", "[Sphere]")
|
|||||||
{
|
{
|
||||||
Ray r(Tuple::Point(0, 0, 5), Tuple::Vector(0, 0, 1));
|
Ray r(Tuple::Point(0, 0, 5), Tuple::Vector(0, 0, 1));
|
||||||
Sphere s;
|
Sphere s;
|
||||||
auto xs = r.intersect(s);
|
Intersections xs = r.intersect(s);
|
||||||
|
|
||||||
REQUIRE(xs.size() == 2);
|
REQUIRE(xs.count() == 2);
|
||||||
REQUIRE(xs[0] == -6.0);
|
REQUIRE(xs[0].distance_t() == -6.0);
|
||||||
REQUIRE(xs[1] == -4.0);
|
REQUIRE(xs[1].distance_t() == -4.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@@ -143,7 +143,6 @@ TEST_CASE("[05][Rays] An intersection encapsulates t and object", "[Intersection
|
|||||||
REQUIRE(i.object() == s);
|
REQUIRE(i.object() == s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
TEST_CASE("[05][Rays] Aggregating intersections", "[Intersections]")
|
TEST_CASE("[05][Rays] Aggregating intersections", "[Intersections]")
|
||||||
@@ -154,7 +153,19 @@ TEST_CASE("[05][Rays] Aggregating intersections", "[Intersections]")
|
|||||||
Intersections xs = Intersections(i1, i2);
|
Intersections xs = Intersections(i1, i2);
|
||||||
|
|
||||||
REQUIRE(xs.count() == 2);
|
REQUIRE(xs.count() == 2);
|
||||||
REQUIRE(xs[0].t() == 1);
|
REQUIRE(xs[0].distance_t() == 1);
|
||||||
REQUIRE(xs[1].t() == 2);
|
REQUIRE(xs[1].distance_t() == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
TEST_CASE("[05][Rays] Intersect set the object on the intersection", "[Intersections]")
|
||||||
|
{
|
||||||
|
Ray r(Tuple::Point(0, 0, 5), Tuple::Vector(0, 0, 1));
|
||||||
|
Sphere s;
|
||||||
|
Intersections xs = r.intersect(s);
|
||||||
|
|
||||||
|
REQUIRE(xs.count() == 2);
|
||||||
|
REQUIRE(xs[0].object() == s);
|
||||||
|
REQUIRE(xs[1].object() == s);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
Reference in New Issue
Block a user