[FEAT] Add a new intersections objects

This commit is contained in:
NADAL Jean-Baptiste
2024-02-12 12:23:57 +01:00
parent af1b3ed2be
commit 6571fe27ee
10 changed files with 247 additions and 29 deletions

View File

@@ -1,5 +1,7 @@
[![Build Status](https://drone.nadal-fr.com/api/badges/raytracing/raytracing_challenge/status.svg)](https://drone.nadal-fr.com/raytracing/raytracing_challenge)
## Le Livre est ici:
https://lire.amazon.fr/?asin=B07Q84TQ91&ref_=kwl_kr_iv_rec_1

View File

@@ -11,6 +11,7 @@ add_library(raytracing
src/common.cpp
src/color.cpp
src/intersection.cpp
src/intersections.cpp
src/matrix.cpp
src/object.cpp
src/ray.cpp

View File

@@ -28,6 +28,7 @@
#include "color.h"
#include "common.h"
#include "intersection.h"
#include "intersections.h"
#include "matrix.h"
#include "ray.h"
#include "sphere.h"

View File

@@ -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(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)
{
return m_distance_t;

View File

@@ -37,7 +37,11 @@ namespace Raytracer
class Intersection
{
public:
Intersection(void);
Intersection(double a_distance_t, Object an_object);
Intersection(Intersection &an_intersection);
const Intersection &operator=(const Intersection &an_intersection);
double distance_t(void);
Object &object(void);

View 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;
}

View 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

View File

@@ -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);
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 discriminant = std::pow(the_b, 2) - 4 * the_a * the_c;
double the_sqrt = std::sqrt(discriminant);
if (discriminant >= 0)
{
the_result.resize(2);
the_result[0] = (-the_b - std::sqrt(discriminant)) / (2 * the_a);
the_result[1] = (-the_b + std::sqrt(discriminant)) / (2 * the_a);
the_intersections.set(Intersection((-the_b - the_sqrt) / (2 * the_a), a_sphere),
Intersection((-the_b + the_sqrt) / (2 * the_a), a_sphere)
);
}
return the_result;
return the_intersections;
}

View File

@@ -30,6 +30,7 @@
#include <vector>
#include "intersections.h"
#include "sphere.h"
#include "tuple.h"
@@ -46,7 +47,7 @@ namespace Raytracer
const Tuple &direction(void) const;
Tuple position(double a_distance);
std::vector<double> intersect(Sphere a_sphere);
Intersections intersect(Sphere a_sphere);
private:
Tuple m_origin;

View File

@@ -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));
Sphere s;
auto xs = r.intersect(s);
Intersections xs = r.intersect(s);
REQUIRE(xs.size() == 2);
REQUIRE(xs[0] == 4.0);
REQUIRE(xs[1] == 6.0);
REQUIRE(xs.count() == 2);
REQUIRE(xs[0].distance_t() == 4.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));
Sphere s;
auto xs = r.intersect(s);
Intersections xs = r.intersect(s);
REQUIRE(xs.size() == 2);
REQUIRE(xs[0] == 5.0);
REQUIRE(xs[1] == 5.0);
REQUIRE(xs.count() == 2);
REQUIRE(xs[0].distance_t() == 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));
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));
Sphere s;
auto xs = r.intersect(s);
Intersections xs = r.intersect(s);
REQUIRE(xs.size() == 2);
REQUIRE(xs[0] == -1.0);
REQUIRE(xs[1] == 1.0);
REQUIRE(xs.count() == 2);
REQUIRE(xs[0].distance_t() == -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));
Sphere s;
auto xs = r.intersect(s);
Intersections xs = r.intersect(s);
REQUIRE(xs.size() == 2);
REQUIRE(xs[0] == -6.0);
REQUIRE(xs[1] == -4.0);
REQUIRE(xs.count() == 2);
REQUIRE(xs[0].distance_t() == -6.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);
}
#if 0
/* ------------------------------------------------------------------------- */
TEST_CASE("[05][Rays] Aggregating intersections", "[Intersections]")
@@ -154,7 +153,19 @@ TEST_CASE("[05][Rays] Aggregating intersections", "[Intersections]")
Intersections xs = Intersections(i1, i2);
REQUIRE(xs.count() == 2);
REQUIRE(xs[0].t() == 1);
REQUIRE(xs[1].t() == 2);
REQUIRE(xs[0].distance_t() == 1);
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