Skip to content

Commit

Permalink
Triangles!!!
Browse files Browse the repository at this point in the history
  • Loading branch information
Godzil committed Feb 25, 2020
1 parent 2ea4abd commit aded6bb
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 2 deletions.
2 changes: 1 addition & 1 deletion source/include/cube.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

class Cube : public Shape {
private:
void checkAxis(double axeOrigine, double axeDirection, double *axeMin, double *axeMax);
void checkAxis(double axeOrigin, double axeDirection, double *axeMin, double *axeMax);

Intersect localIntersect(Ray r);

Expand Down
1 change: 1 addition & 0 deletions source/include/shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum ShapeType
SHAPE_CYLINDER,
SHAPE_CONE,
SHAPE_GROUP,
SHAPE_TRIANGLE,

};

Expand Down
28 changes: 28 additions & 0 deletions source/include/triangle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* DoRayMe - a quick and dirty Raytracer
* Triangle header
*
* Created by Manoël Trapier
* Copyright (c) 2020 986-Studio.
*
*/
#ifndef DORAYME_TRIANGLE_H
#define DORAYME_TRIANGLE_H

#include <shape.h>

class Triangle : public Shape
{
Intersect localIntersect(Ray r);
Tuple localNormalAt(Tuple point);

public:
Tuple p1, p2, p3;
Tuple e1, e2;
Tuple normal;

public:
Triangle(Point p1, Point p2, Point p3);
};

#endif /* DORAYME_TRIANGLE_H */
57 changes: 57 additions & 0 deletions source/shapes/triangle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* DoRayMe - a quick and dirty Raytracer
* Cone implementation
*
* Created by Manoël Trapier
* Copyright (c) 2020 986-Studio.
*
*/
#include <ray.h>
#include <shape.h>
#include <triangle.h>
#include <math_helper.h>

Triangle::Triangle(Point p1, Point p2, Point p3) : Shape(SHAPE_TRIANGLE), p1(p1), p2(p2), p3(p3)
{
this->e1 = p2 - p1;
this->e2 = p3 - p1;
this->normal = e2.cross(e1).normalise();
}

Intersect Triangle::localIntersect(Ray r)
{
Intersect ret;

Tuple dirCrossE2 = r.direction.cross(this->e2);
double determinant = this->e1.dot(dirCrossE2);
if (fabs(determinant) < getEpsilon())
{
return ret;
}

double f = 1.0 / determinant;
Tuple p1ToOrigin = r.origin - this->p1;
Tuple originCrossE1 = p1ToOrigin.cross(this->e1);
double u = f * p1ToOrigin.dot(dirCrossE2);
double v = f * r.direction.dot(originCrossE1);

if ((u < 0) || (u > 1))
{
return ret;
}

if ((v < 0) || ((u + v) > 1))
{
return ret;
}

double t = f * this->e2.dot(originCrossE1);
ret.add(Intersection(t, this));

return ret;
}

Tuple Triangle::localNormalAt(Tuple point)
{
return this->normal;
}
2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ find_package(Threads REQUIRED)
set(TESTS_SRC math_test.cpp tuple_test.cpp colour_test.cpp canvas_test.cpp matrix_test.cpp transformation_test.cpp
ray_test.cpp intersect_test.cpp sphere_test.cpp light_test.cpp material_test.cpp world_test.cpp camera_test.cpp
shape_test.cpp plane_test.cpp pattern_test.cpp cube_test.cpp cylinder_test.cpp cone_test.cpp group_test.cpp
boundingbox_test.cpp)
boundingbox_test.cpp triangle_test.cpp)

add_executable(testMyRays)
target_include_directories(testMyRays PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
Expand Down
91 changes: 91 additions & 0 deletions tests/triangle_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* DoRayMe - a quick and dirty Raytracer
* Triangle unit tests
*
* Created by Manoël Trapier
* Copyright (c) 2020 986-Studio.
*
*/
#include <triangle.h>
#include <math.h>
#include <gtest/gtest.h>

TEST(TriangleTest, Construcring_a_triangle)
{
Point p1 = Point(0, 1, 0);
Point p2 = Point(-1, 0, 0);
Point p3 = Point(1, 0, 0);

Triangle t = Triangle(p1, p2, p3);

ASSERT_EQ(t.p1, p1);
ASSERT_EQ(t.p2, p2);
ASSERT_EQ(t.p3, p3);
ASSERT_EQ(t.e1, Vector(-1, -1, 0));
ASSERT_EQ(t.e2, Vector(1, -1, 0));
ASSERT_EQ(t.normal, Vector(0, 0, -1));
}

TEST(TriangleTest, Finding_the_normal_on_a_triangle)
{
Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0));

Tuple n1 = t.normalAt(Point(0, 0.5, 0));
Tuple n2 = t.normalAt(Point(-0.5, 0.75, 0));
Tuple n3 = t.normalAt(Point(0.5, 0.25, 0));

ASSERT_EQ(n1, t.normal);
ASSERT_EQ(n2, t.normal);
ASSERT_EQ(n3, t.normal);
}

TEST(TriangleTest, Intersecting_a_ray_parallel_to_the_triangle)
{
Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0));
Ray r = Ray(Point(0, -1, -2), Vector(0, 1, 0));

Intersect xs = t.intersect(r);

ASSERT_EQ(xs.count(), 0);
}

TEST(TriangleTest, A_ray_miss_the_p1_p3_edge)
{
Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0));
Ray r = Ray(Point(1, 1, -2), Vector(0, 0, 1));

Intersect xs = t.intersect(r);

ASSERT_EQ(xs.count(), 0);
}

TEST(TriangleTest, A_ray_miss_the_p1_p2_edge)
{
Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0));
Ray r = Ray(Point(-1, 1, -2), Vector(0, 0, 1));

Intersect xs = t.intersect(r);

ASSERT_EQ(xs.count(), 0);
}

TEST(TriangleTest, A_ray_miss_the_p2_p3_edge)
{
Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0));
Ray r = Ray(Point(0, -1, -2), Vector(0, 0, 1));

Intersect xs = t.intersect(r);

ASSERT_EQ(xs.count(), 0);
}

TEST(TriangleTest, A_ray_strikes_a_triangle)
{
Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0));
Ray r = Ray(Point(0, .5, -2), Vector(0, 0, 1));

Intersect xs = t.intersect(r);

ASSERT_EQ(xs.count(), 1);
EXPECT_EQ(xs[0].t, 2);
}

0 comments on commit aded6bb

Please sign in to comment.