add interval

This commit is contained in:
zongor 2025-07-24 14:55:28 -04:00
parent 82984e1a5a
commit 5bbfb17684
6 changed files with 77 additions and 42 deletions

View File

@ -62,7 +62,7 @@ private:
Color ray_color(const Ray &r, const hittable &world) { Color ray_color(const Ray &r, const hittable &world) {
hit_record rec; hit_record rec;
if (world.hit(r, 0, infinity, rec)) { if (world.hit(r, interval(0, infinity), rec)) {
return 0.5 * (rec.normal + Color(1, 1, 1)); return 0.5 * (rec.normal + Color(1, 1, 1));
} }

View File

@ -2,10 +2,11 @@
#define RTWEEKEND_H #define RTWEEKEND_H
#include <cmath> #include <cmath>
#include <cstdlib>
#include <iostream> #include <iostream>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <random>
// C++ Std Usings // C++ Std Usings
@ -23,10 +24,22 @@ inline double degrees_to_radians(double degrees) {
return degrees * pi / 180.0; return degrees * pi / 180.0;
} }
inline double random_double() {
static std::uniform_real_distribution<double> distribution(0.0, 1.0);
static std::mt19937 generator;
return distribution(generator);
}
inline double random_double(double min, double max) {
// Returns a random real in [min,max).
return min + (max - min) * random_double();
}
// Common Headers // Common Headers
#include "canvas.h"
#include "interval.h"
#include "ray.h" #include "ray.h"
#include "vec3.h" #include "vec3.h"
#include "canvas.h"
#endif #endif

View File

@ -14,7 +14,7 @@ class hittable {
public: public:
virtual ~hittable() = default; virtual ~hittable() = default;
virtual bool hit(const Ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const = 0; virtual bool hit(const Ray &r, interval ray_t, hit_record &rec) const = 0;
}; };
#endif #endif

View File

@ -20,14 +20,13 @@ public:
void add(shared_ptr<hittable> object) { objects.push_back(object); } void add(shared_ptr<hittable> object) { objects.push_back(object); }
bool hit(const Ray &r, double ray_tmin, double ray_tmax, bool hit(const Ray &r, interval ray_t, hit_record &rec) const override {
hit_record &rec) const override {
hit_record temp_rec; hit_record temp_rec;
bool hit_anything = false; bool hit_anything = false;
auto closest_so_far = ray_tmax; auto closest_so_far = ray_t.max;
for (const auto &object : objects) { for (const auto &object : objects) {
if (object->hit(r, ray_tmin, closest_so_far, temp_rec)) { if (object->hit(r, interval(ray_t.min, closest_so_far), temp_rec)) {
hit_anything = true; hit_anything = true;
closest_so_far = temp_rec.t; closest_so_far = temp_rec.t;
rec = temp_rec; rec = temp_rec;

22
src/interval.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef INTERVAL_H
#define INTERVAL_H
class interval {
public:
double min, max;
interval() : min(+infinity), max(-infinity) {} // Default interval is empty
interval(double min, double max) : min(min), max(max) {}
double size() const { return max - min; }
bool contains(double x) const { return min <= x && x <= max; }
bool surrounds(double x) const { return min < x && x < max; }
};
static inline const interval empty = interval(+infinity, -infinity);
static inline const interval universe = interval(-infinity, +infinity);
#endif

View File

@ -6,9 +6,10 @@
class sphere : public hittable { class sphere : public hittable {
public: public:
sphere(const Point3& center, double radius) : center(center), radius(std::fmax(0,radius)) {} sphere(const Point3 &center, double radius)
: center(center), radius(std::fmax(0, radius)) {}
bool hit(const Ray& r, double ray_tmin, double ray_tmax, hit_record& rec) const override { bool hit(const Ray &r, interval ray_t, hit_record &rec) const override {
Vec3 oc = center - r.origin(); Vec3 oc = center - r.origin();
auto a = r.direction().length_squared(); auto a = r.direction().length_squared();
auto h = dot(r.direction(), oc); auto h = dot(r.direction(), oc);
@ -22,9 +23,9 @@ class sphere : public hittable {
// Find the nearest root that lies in the acceptable range. // Find the nearest root that lies in the acceptable range.
auto root = (h - sqrtd) / a; auto root = (h - sqrtd) / a;
if (root <= ray_tmin || ray_tmax <= root) { if (!ray_t.surrounds(root)) {
root = (h + sqrtd) / a; root = (h + sqrtd) / a;
if (root <= ray_tmin || ray_tmax <= root) if (!ray_t.surrounds(root))
return false; return false;
} }