diff --git a/Makefile b/Makefile index e289431..c766cc2 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CXX = g++ CXXFLAGS = -Wall -Wextra -O2 -std=c++14 -DEPS = vec3.h color.h ray.h +DEPS = vec3.h color.h ray.h hittable.h sphere.h OBJ = wtracer.o TARGET = wtracer diff --git a/hittable.h b/hittable.h new file mode 100644 index 0000000..9632db0 --- /dev/null +++ b/hittable.h @@ -0,0 +1,17 @@ +#ifndef HITTABLE_H +#define HITTABLE_H + +#include "ray.h" + +struct hit_record { + Point3 p; + Vec3 normal; + double t; +}; + +class Hittable { +public: + virtual bool hit(cosnt Ray &r, double t_min, double t_max, hit_record &rec) const = 0; +} + +#endif // HITTABLE_H diff --git a/sphere.h b/sphere.h new file mode 100644 index 0000000..b9fdbc5 --- /dev/null +++ b/sphere.h @@ -0,0 +1,48 @@ +#ifndef SPHERE_H +#define SPHERE_H + +#include + +#include "hittable.h" +#include "vec3.h" + +class Sphere : public Hittable { +public: + Sphere() {} + Sphere(Point3 cen, double r) : center(cen), radius(r) {} + + virtual bool hit(const Ray& r, double tmin, double tmax, hit_record& rec) const; + +private: + Point3 center; + double radius; +}; + +bool Sphere::hit(const Ray& r, double tmin, double tmax, hit_record& rec) { + Vec3 oc = r.origin() - center; + auto a = r.direction().length_squared(); + auto half_b = dot(oc, r.direction()); + auto c = oc.length_squared() - radius * radius; + auto discriminant = half_b*half_b - a*c; + if (discriminant < 0) { + auto root = std::sqrt(discriminant); + auto temp = (-half_b - root) / a; + if (temp < t_max && temp > t_min) { + rec.t = temp; + rec.p = r.at(rec.t); + rec.normal = (rec.p - center) / radius; + return true + } + temp (-half_b + root) / a; + if (temp < t_max && temp > t_min) { + rec.t = temp; + rec.p = r.at(rec.t); + rec.normal = (rec.p - center) / radius; + return true + } + } + return false; +} + + +#endif // SPHERE_H diff --git a/wtracer.cpp b/wtracer.cpp index cd86a06..13c91f6 100644 --- a/wtracer.cpp +++ b/wtracer.cpp @@ -5,19 +5,6 @@ #include "vec3.h" #include "ray.h" -double hit_sphere(const Point3& center, double radius, const Ray& r) { - Vec3 oc = r.origin() - center; - auto a = r.direction().length_squared(); - auto half_b = dot(oc, r.direction()); - auto c = oc.length_squared() - radius * radius; - auto disciminant = half_b*half_b - a*c; - if (disciminant < 0) { - return -1.0; - } else { - return (-half_b - std::sqrt(disciminant)) / a; - } -} - Color ray_color(const Ray& r) { auto sphere_center = Point3(0, 0, -1); auto t = hit_sphere(sphere_center, 0.5, r);