text: //
  //  sphere.hpp
  //  RTIOW
  //
  // This class serves to define the geometry of a sphere.
  //
  //  Created by Philippe Nadon on 2019-06-05.
  //  Copyright © 2019 Philippe Nadon. All rights reserved.
  //
  
  #ifndef sphere_hpp
  #define sphere_hpp
  
  #include "hitable.hpp"
  
  class sphere: public hitable {
  public:
      sphere() {}
      sphere(vec3 cen, float r, material *m): center(cen), radius(r), mat_ptr(m) {};
      virtual bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const;
      virtual bool bounding_box(float t0, float t1, aabb& box) const;
      vec3 center;
      float radius;
      material *mat_ptr;
  };
  
  /*
  * Creates a bounding box, used to optimize when the sphere is checked for collisions.
  */
  bool sphere::bounding_box(float t0, float t1, aabb& box) const {
      box = aabb(center - vec3(radius, radius, radius),
                 center + vec3(radius, radius, radius));
      return true;
  }
  
  /*
  * Determines how light interacts with the surface of the sphere.
  */
  bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const {
      vec3 oc = r.origin() - center;
      float a = dot(r.direction(), r.direction());
      float b = dot(oc, r.direction());
      float c = dot(oc, oc) - radius * radius;
      float discriminant = b * b - a * c;
      if (discriminant > 0) {
          float temp = (-b - sqrt(b * b - a * c)) / a;
          if (temp < t_max && temp > t_min) {
              rec.t = temp;
              rec.p = r.point(rec.t);
              get_sphere_uv((rec.p - center) / radius, rec.u, rec.v);
              rec.normal = (rec.p - center) / radius;
              rec.mat_ptr = mat_ptr;
              return true;
          }
          temp = (-b + sqrt( b * b - a * c)) / a;
          if (temp < t_max && temp > t_min) {
              rec.t = temp;
              rec.p = r.point(rec.t);
              get_sphere_uv((rec.p - center) / radius, rec.u, rec.v);
              rec.normal = (rec.p - center) / radius;
              rec.mat_ptr = mat_ptr;
              return true;
          }
      }
      return false;
  }
  
  #endif /* sphere_hpp */
  