Skip to content

Commit

Permalink
ray4: use new Ray4 class
Browse files Browse the repository at this point in the history
  • Loading branch information
hollasch committed Oct 31, 2024
1 parent 5d69cbc commit baba69d
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 73 deletions.
5 changes: 4 additions & 1 deletion ray4/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ set ( sources_ray4
src/r4_color.h
src/r4_image.h
src/r4_point.h
src/r4_ray.h
src/r4_vector.h
src/r4_color.cpp
src/r4_hit.cpp
src/r4_io.cpp
src/r4_main.cpp
src/r4_parse.cpp
src/r4_point.cpp
src/r4_ray.cpp
src/r4_trace.cpp
src/r4_vector.cpp
)
Expand All @@ -47,8 +49,9 @@ FetchContent_MakeAvailable(Catch2)
add_executable(tests
src/r4_test.cpp
src/r4_color.cpp
src/r4_vector.cpp
src/r4_point.cpp
src/r4_ray.cpp
src/r4_vector.cpp
)

target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
64 changes: 30 additions & 34 deletions ray4/src/r4_hit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@
//
// The functions take the following parameter list:
//
// objptr (ObjInfo*): Pointer to the Object Structure
// rayO (Point4 ): Ray Origin
// rayD (Vector4 ): Ray Direction (Must Be A Unit Vector)
// mindist (double* ): Closest Intersection Distance So Far
// intr (Point4* ): Intersection Point
// normal (Vector4*): Surface Normal at Intersection Point
// ObjInfo* objptr : Pointer to the Object Structure
// Ray4 ray : Ray Origin
// double *mindist: Closest Intersection Distance So Far
// Point4 *intr : Intersection Point
// Vector4 *normal : Surface Normal at Intersection Point
//
// If the ray does not intersect the object, the intersection function returns false and does not
// alter `mindist', `intr' or `normal'.
Expand Down Expand Up @@ -75,12 +74,11 @@


bool HitSphere (
ObjInfo *objptr, // Sphere to Test
Point4 rayO, // Ray Origin
Vector4 rayD, // Ray Direction
double *mindist, // Previous Minimum Distance
Point4 *intr, // Intersection Point
Vector4 *normal) // Surface Normal @ Intersection Point
ObjInfo *objptr, // Sphere to Test
const Ray4 &ray, // Trace Ray
double *mindist, // Previous Minimum Distance
Point4 *intr, // Intersection Point
Vector4 *normal) // Surface Normal @ Intersection Point
{
// This is the intersection function for hyperspheres.

Expand All @@ -91,9 +89,9 @@ bool HitSphere (
double rad; // Radical Value
double t1,t2; // Intersection Ray Parameters

cdir = sphere.center - rayO;
cdir = sphere.center - ray.origin;

bb = dot(cdir, rayD);
bb = dot(cdir, ray.direction);
rad = (bb * bb) - dot(cdir, cdir) + sphere.rsqrd;

if (rad < 0.0)
Expand Down Expand Up @@ -121,7 +119,7 @@ bool HitSphere (
*mindist = t1;

if (intr)
(*intr) = rayO + t1*rayD;
(*intr) = ray(t1);

if (normal)
*normal = (*intr - sphere.center) / sphere.radius;
Expand All @@ -131,12 +129,11 @@ bool HitSphere (

//==================================================================================================
bool HitTetPar (
ObjInfo *objptr, // Sphere to Test
Point4 rayO, // Ray Origin
Vector4 rayD, // Ray Direction
double *mindist, // Previous Minimum Distance
Point4 *intersect, // Intersection Point
Vector4 *normal) // Surface Normal @ Intersection Point
ObjInfo *objptr, // Sphere to Test
const Ray4 &ray, // Trace Ray
double *mindist, // Previous Minimum Distance
Point4 *intersect, // Intersection Point
Vector4 *normal) // Surface Normal @ Intersection Point
{
// This is the intersection function for 4D tetrahedrons and parallelepipeds. Note that if the
// object is a tetrahedron and the conditions are met to set the intersection values, then the
Expand All @@ -155,12 +152,12 @@ bool HitTetPar (

// Find the ray parameter to intersect the hyperplane.

rayT = dot(tp->normal, rayD);
rayT = dot(tp->normal, ray.direction);

if (fabs(rayT) < epsilon) // If the ray is parallel to the hyperplane.
return false;

rayT = (-tp->planeConst - dot(tp->normal, rayO.toVector())) / rayT;
rayT = (-tp->planeConst - dot(tp->normal, ray.origin.toVector())) / rayT;

if (rayT < 0.0) // If the object is behind the ray.
return false;
Expand All @@ -171,7 +168,7 @@ bool HitTetPar (
if (mindist && (*mindist > 0) && ((rayT < MINDIST) || (rayT > *mindist)))
return false;

intr = rayO + (rayT * rayD);
intr = ray(rayT);

// Now we need to find the barycentric coordinates of the 4D object to determine if the
// ray/hyperplane intersection point is inside of the 4D object. To simplify the process,
Expand Down Expand Up @@ -283,12 +280,11 @@ bool HitTetPar (

//==================================================================================================
bool HitTriangle (
ObjInfo *objptr, // Sphere to Test
Point4 rayO, // Ray Origin
Vector4 rayD, // Ray Direction
double *mindist, // Previous Minimum Distance
Point4 *intersect, // Intersection Point
Vector4 *normal) // Surface Normal @ Intersection Point
ObjInfo *objptr, // Sphere to Test
const Ray4 &ray, // Trace Ray
double *mindist, // Previous Minimum Distance
Point4 *intersect, // Intersection Point
Vector4 *normal) // Surface Normal @ Intersection Point
{
// This is the intersection routine for 2D triangles in 4-space. If the ray intersects triangle
// and the conditions are met to set the intersection specifics, then the barycentric
Expand Down Expand Up @@ -316,12 +312,12 @@ bool HitTriangle (
// V0 a vertex of the triangle, vec1 is the vector from V0 to another vertex, and vec2 is the
// vector from V0 to the other vertex.

auto vecTemp2 = cross(rayD, TRI->vec1, TRI->vec2);
auto vecTemp2 = cross(ray.direction, TRI->vec1, TRI->vec2);
div = vecTemp2.normSquared();
if (div < epsilon)
return false;

auto vecTemp1 = cross(TRI->vert[0] - rayO, TRI->vec1, TRI->vec2);
auto vecTemp1 = cross(TRI->vert[0] - ray.origin, TRI->vec1, TRI->vec2);

rayT = dot(vecTemp1, vecTemp2) / div;

Expand All @@ -337,7 +333,7 @@ bool HitTriangle (
if (mindist && (*mindist > 0) && ((rayT < MINDIST) || (rayT > *mindist)))
return false;

intr = rayO + (rayT * rayD);
intr = ray(rayT);

// Compute the triangle normal vector. Since the triangle is embedded in 2-space, we've got an
// extra degree of freedom floating around, so we need to do some jazz to pin it down. To do
Expand All @@ -348,7 +344,7 @@ bool HitTriangle (
// computationally).

{
auto Vtemp = cross(rayD, TRI->vec1, TRI->vec2);
auto Vtemp = cross(ray.direction, TRI->vec1, TRI->vec2);
_normal = cross(Vtemp, TRI->vec1, TRI->vec2);
}

Expand Down
10 changes: 5 additions & 5 deletions ray4/src/r4_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,20 +598,20 @@ void FireRays () {

for (Xindex=iheader.start[X]; Xindex <= iheader.end[X]; ++Xindex) {
Color color; // Pixel Color
Vector4 Dir; // Ray Direction Vector
Vector4 dir; // Ray Direction Vector
Point4 Gpoint; // Current Grid Point
double norm; // Vector Norm Value

// Calculate the unit ViewFrom-RayDirection vector.

Gpoint = Yorigin + (Xindex*Gx);
Dir = Gpoint - Vfrom;
norm = Dir.norm();
Dir /= norm;
dir = Gpoint - Vfrom;
norm = dir.norm();
dir /= norm;

// Fire the ray.

RayTrace (Vfrom, Dir, color, 0);
RayTrace (Ray4(Vfrom, dir), color, 0);

// Scale the resulting color to 0-255.

Expand Down
38 changes: 38 additions & 0 deletions ray4/src/r4_ray.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//**************************************************************************************************
// Copyright (c) 1991-2024 Steven R Hollasch
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//**************************************************************************************************

#include "ray4.h"


//==================================================================================================
bool Ray4::operator== (const Ray4& other) const {
return origin == other.origin && direction == other.direction;
}

//==================================================================================================
bool Ray4::operator!= (const Ray4& other) const {
return !(*this == other);
}

//==================================================================================================
Point4 Ray4::operator() (double t) const {
return origin + t*direction;
}
48 changes: 48 additions & 0 deletions ray4/src/r4_ray.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//**************************************************************************************************
// Copyright (c) 1991-2024 Steven R Hollasch
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software
// and associated documentation files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//**************************************************************************************************
#ifndef R4_RAY_H
#define R4_RAY_H

#include "r4_vector.h"
#include "r4_point.h"


class Ray4 {
// A ray (with origin and direction) in four-dimensional space.

public:
Point4 origin;
Vector4 direction;

Ray4() = default;
Ray4(const Ray4&) = default;
~Ray4() = default;
Ray4& operator= (const Ray4 &other) = default;

Ray4(Point4 origin, Vector4 direction) : origin(origin), direction(direction) {}

bool operator== (const Ray4& other) const;
bool operator!= (const Ray4& other) const;

Point4 operator() (double t) const;
};

#endif
23 changes: 23 additions & 0 deletions ray4/src/r4_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "r4_color.h"
#include "r4_vector.h"
#include "r4_point.h"
#include "r4_ray.h"

namespace Catch {
// Color to String
Expand Down Expand Up @@ -240,3 +241,25 @@ TEST_CASE("Point tests", "[point4]") {
CHECK(Point4(10,10,10,10) - Vector4(4,5,6,7) == Point4(6,5,4,3));
}
}

//==================================================================================================
TEST_CASE("Ray tests", "[ray]") {
SECTION("Ray equality") {
REQUIRE(Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)) == Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)));
REQUIRE_FALSE(Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)) == Ray4(Point4(1,2,3,4),Vector4(0,7,8,9)));
REQUIRE_FALSE(Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)) == Ray4(Point4(0,2,3,4),Vector4(6,7,8,9)));

REQUIRE(Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)) != Ray4(Point4(1,2,3,4),Vector4(0,7,8,9)));
REQUIRE(Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)) != Ray4(Point4(0,2,3,4),Vector4(6,7,8,9)));
REQUIRE_FALSE(Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)) != Ray4(Point4(1,2,3,4),Vector4(6,7,8,9)));
}

SECTION("Ray evaluation") {
Ray4 r {Point4(0,0,0,0), Vector4(1,2,3,4)};

CHECK(r( 0.0) == Point4(0,0,0,0));
CHECK(r( 1.0) == Point4(1,2,3,4));
CHECK(r( 2.0) == Point4(2,4,6,8));
CHECK(r(-1.0) == Point4(-1,-2,-3,-4));
}
}
Loading

0 comments on commit baba69d

Please sign in to comment.