add interval
This commit is contained in:
parent
82984e1a5a
commit
5bbfb17684
|
@ -62,7 +62,7 @@ private:
|
|||
|
||||
Color ray_color(const Ray &r, const hittable &world) {
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
19
src/common.h
19
src/common.h
|
@ -2,10 +2,11 @@
|
|||
#define RTWEEKEND_H
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
|
||||
#include <random>
|
||||
|
||||
// C++ Std Usings
|
||||
|
||||
|
@ -20,13 +21,25 @@ const double pi = 3.1415926535897932385;
|
|||
// Utility Functions
|
||||
|
||||
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
|
||||
|
||||
#include "canvas.h"
|
||||
#include "interval.h"
|
||||
#include "ray.h"
|
||||
#include "vec3.h"
|
||||
#include "canvas.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,17 +4,17 @@
|
|||
#include "ray.h"
|
||||
|
||||
class hit_record {
|
||||
public:
|
||||
Point3 p;
|
||||
Vec3 normal;
|
||||
double t;
|
||||
public:
|
||||
Point3 p;
|
||||
Vec3 normal;
|
||||
double t;
|
||||
};
|
||||
|
||||
class hittable {
|
||||
public:
|
||||
virtual ~hittable() = default;
|
||||
public:
|
||||
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
|
||||
|
|
|
@ -20,14 +20,13 @@ public:
|
|||
|
||||
void add(shared_ptr<hittable> object) { objects.push_back(object); }
|
||||
|
||||
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 {
|
||||
hit_record temp_rec;
|
||||
bool hit_anything = false;
|
||||
auto closest_so_far = ray_tmax;
|
||||
auto closest_so_far = ray_t.max;
|
||||
|
||||
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;
|
||||
closest_so_far = temp_rec.t;
|
||||
rec = temp_rec;
|
||||
|
|
|
@ -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
|
55
src/sphere.h
55
src/sphere.h
|
@ -5,39 +5,40 @@
|
|||
#include "vec3.h"
|
||||
|
||||
class sphere : public hittable {
|
||||
public:
|
||||
sphere(const Point3& center, double radius) : center(center), radius(std::fmax(0,radius)) {}
|
||||
public:
|
||||
sphere(const Point3 ¢er, 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 {
|
||||
Vec3 oc = center - r.origin();
|
||||
auto a = r.direction().length_squared();
|
||||
auto h = dot(r.direction(), oc);
|
||||
auto c = oc.length_squared() - radius*radius;
|
||||
bool hit(const Ray &r, interval ray_t, hit_record &rec) const override {
|
||||
Vec3 oc = center - r.origin();
|
||||
auto a = r.direction().length_squared();
|
||||
auto h = dot(r.direction(), oc);
|
||||
auto c = oc.length_squared() - radius * radius;
|
||||
|
||||
auto discriminant = h*h - a*c;
|
||||
if (discriminant < 0)
|
||||
return false;
|
||||
auto discriminant = h * h - a * c;
|
||||
if (discriminant < 0)
|
||||
return false;
|
||||
|
||||
auto sqrtd = std::sqrt(discriminant);
|
||||
auto sqrtd = std::sqrt(discriminant);
|
||||
|
||||
// Find the nearest root that lies in the acceptable range.
|
||||
auto root = (h - sqrtd) / a;
|
||||
if (root <= ray_tmin || ray_tmax <= root) {
|
||||
root = (h + sqrtd) / a;
|
||||
if (root <= ray_tmin || ray_tmax <= root)
|
||||
return false;
|
||||
}
|
||||
|
||||
rec.t = root;
|
||||
rec.p = r.at(rec.t);
|
||||
rec.normal = (rec.p - center) / radius;
|
||||
|
||||
return true;
|
||||
// Find the nearest root that lies in the acceptable range.
|
||||
auto root = (h - sqrtd) / a;
|
||||
if (!ray_t.surrounds(root)) {
|
||||
root = (h + sqrtd) / a;
|
||||
if (!ray_t.surrounds(root))
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Point3 center;
|
||||
double radius;
|
||||
rec.t = root;
|
||||
rec.p = r.at(rec.t);
|
||||
rec.normal = (rec.p - center) / radius;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Point3 center;
|
||||
double radius;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue