# T2 Revise main.cpp (Milestone 1)

#### main.cpp

This is the most important file

### Revising header file section

```cpp
#include "rtweekend.h"

//#include "vec3.h"
//#include "color.h"
//#include "ray.h"
//#include <iostream>

#include "hittable.h"
#include "hittable_list.h"
#include "sphere.h"
```

### Removing hit\_sphere function

We are using the hit() function from the sphere class instead.

You can simply delete it.

```cpp
/*
double hit_sphere(const point3& center, double radius, const ray& r) {
    vec3 oc = center - r.origin();
    auto a = dot(r.direction(), r.direction());
    auto b = -2.0 * dot(r.direction(), oc);
    auto c = dot(oc, oc) - radius*radius;
    auto discriminant = b*b - 4*a*c;

    if (discriminant < 0) {
        return -1.0;
    } else {
        return (-b - std::sqrt(discriminant) ) / (2.0*a);
    }
}
*/
```

### Revising ray\_color function

Now we are using the hit() function instead.

```cpp
color ray_color(const ray& r, const hittable & world) {
    /*
    auto t = hit_sphere(point3(0,0,-1), 0.5, r);
    if (t > 0.0) {
        vec3 N = unit_vector(r.at(t) - vec3(0,0,-1));
        return 0.5*color(N.x()+1, N.y()+1, N.z()+1);
    }
    */

    hit_record rec;
    if (world.hit(r, 0, infinity, rec)) {
        return 0.5 * (rec.normal + color(1,1,1));
    }
    
    vec3 unit_direction = unit_vector(r.direction());
    auto a = 0.25*(unit_direction.y() + unit_direction.x() + 2.0);
    return (1.0 - a)*color(1.0, 0.0, 0.0) + a * color(0.0, 0.0, 1.0);
}
```

### Revising the main() to use the object list

```cpp
#include "rtweekend.h"

//#include "vec3.h"
//#include "color.h"
//#include "ray.h"
//#include <iostream>

#include "hittable.h"
#include "hittable_list.h"
#include "sphere.h"

/*
double hit_sphere(const point3& center, double radius, const ray& r) {
    vec3 oc = center - r.origin();
    auto a = dot(r.direction(), r.direction());
    auto b = -2.0 * dot(r.direction(), oc);
    auto c = dot(oc, oc) - radius*radius;
    auto discriminant = b*b - 4*a*c;

    if (discriminant < 0) {
        return -1.0;
    } else {
        return (-b - std::sqrt(discriminant) ) / (2.0*a);
    }
}
*/


//color ray_color(const ray& r) {
color ray_color(const ray& r, const hittable & world) {    
    /*
    auto t = hit_sphere(point3(0,0,-1), 0.5, r);
    if (t > 0.0) {
        vec3 N = unit_vector(r.at(t) - vec3(0,0,-1));
        return 0.5*color(N.x()+1, N.y()+1, N.z()+1);
    }
    */

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


    vec3 unit_direction = unit_vector(r.direction());
    auto a = 0.25*(unit_direction.y() + unit_direction.x() + 2.0);
    return (1.0 - a)*color(1.0, 0.0, 0.0) + a * color(0.0, 0.0, 1.0);
}

int main() {

    // Image
    auto aspect_ratio = 16.0 / 9.0;
    int image_width = 400;

    // Calculate the image height, and ensure that it's at least 1.
    int image_height = int(image_width / aspect_ratio);
    image_height = (image_height < 1) ? 1 : image_height;

    // =====================================================
    // World
    // adding two spheres to the world
    // you need to add triangle models in your coursework 2

    hittable_list world;

    world.add(make_shared<sphere>(point3(0,0,-1), 0.5));
    world.add(make_shared<sphere>(point3(0,-100.5,-1), 100));
    // =====================================================


    // Camera
    auto focal_length = 1.0;  // distance to the viewport plane
    auto camera_center = point3(0, 0, 0);

    // viewport size
    auto viewport_height = 2.0;
    auto viewport_width = viewport_height * (double(image_width)/image_height);
    
    // Calculate the vectors across the horizontal and down the vertical viewport edges.
    auto viewport_u = vec3(viewport_width, 0, 0);
    auto viewport_v = vec3(0, -viewport_height, 0);

    // Calculate the horizontal and vertical delta vectors from pixel to pixel.
    auto pixel_delta_u = viewport_u / image_width;
    auto pixel_delta_v = viewport_v / image_height;


    // Calculate the location of the upper left pixel.
    auto viewport_upper_left = camera_center
                             - vec3(0, 0, focal_length) 
                             - viewport_u/2 - viewport_v/2;
    auto pixel00_loc = viewport_upper_left + 0.5 * (pixel_delta_u + pixel_delta_v);


    // Render

    std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";

    for (int j = 0; j < image_height; j++) {
        std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush;
        for (int i = 0; i < image_width; i++) {
             // calculate the pixel position in the world space
            auto pixel_center = pixel00_loc + (i * pixel_delta_u) + (j * pixel_delta_v);
            // calculate the ray direction using the camera position
            auto ray_direction = pixel_center - camera_center;
            // build the ray
            ray r(camera_center, ray_direction);

            // ============================================
            //color pixel_color = ray_color(r);
            color pixel_color = ray_color(r, world);
            // ============================================


            write_color(std::cout, pixel_color);
        }
    }

    std::clog << "\rDone.                 \n";
}
```

### Build and Run your program

You may find errors at this point because you have changed many files.

If successful, run your program you will see something like the following:

```
./ray01.exe > image5.ppm
```

<figure><img src="https://3464970502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3JUKGJZ67JX02QZdPhsy%2Fuploads%2FYdnFNj4IIBQigaLi36MG%2F9af635e3-eec2-428c-a296-4e7b8f73ade8.png?alt=media&#x26;token=f40a06bb-c6d7-4be2-b9ce-4060f0341cd4" alt=""><figcaption></figcaption></figure>
