# T3 Add interval.h

### Add the following source code

Create interval.h under the src folder

```cpp
#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 const interval empty, universe;
};

const interval interval::empty    = interval(+infinity, -infinity);
const interval interval::universe = interval(-infinity, +infinity);

#endif
```

#### Revise rtweekend.h

```cpp
// Common Headers
#include "color.h"
#include "interval.h"
#include "ray.h"
#include "vec3.h"
```

### Revise hittable, hittable\_list, sphere to use intervals

#### hittable

```cpp
    //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;
```

#### hittable\_list

```cpp
class hittable_list : public hittable {
  public:
    //...

    //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;
            }
        }
        return hit_anything;
    }
};
```

#### sphere

```cpp
class sphere : public hittable {
  private:
    point3 center;
    double radius;
    
  public:
    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();
        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 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;
        }
        */
        if (!ray_t.surrounds(root)) {
            root = (h + sqrtd) / a;
            if (!ray_t.surrounds(root))
                return false;
        }

        rec.t = root;
        rec.p = r.at(rec.t);
        rec.normal = (rec.p - center) / radius;
        vec3 outward_normal = (rec.p - center) / radius;
        rec.set_face_normal(r, outward_normal);

        return true;
    }

};
```

#### main.cpp

in function **ray\_color**, make following changes

```cpp
    // if (world.hit(r, 0, infinity, rec)) {
    if (world.hit(r, interval(0, infinity), rec)) {
        return 0.5 * (rec.normal + color(1,1,1));
    }
```

#### Build Your Program

&#x20;to make sure everything is correct
