# T4 Use the Camera Class

### Create camera.h

Create camera.h under your src folder, put the following framework into it

```cpp
#ifndef CAMERA_H
#define CAMERA_H

#include "hittable.h"

class camera {
private:
    /* Private Camera Variables Here */

    void initialize() {
        //...
    }
    
    color ray_color(const ray& r, const hittable& world) const {
        //...
    }
    
  public:
    /* Public Camera Parameters Here */

    void render(const hittable& world) {
        //...
    }

};

#endif
```

### Filling the methods

#### ray\_color()

move the content in ray\_color() in main.cpp to this method

```cpp
    color ray_color(const ray& r, const hittable& world) const {
        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));
        }


        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);
    }
```

#### intialise()

Move the variables and initialisation code from main.cpp to the camera class

```cpp
  private:
    int    image_height;   // Rendered image height
    point3 center;         // Camera center
    point3 pixel00_loc;    // Location of pixel 0, 0
    vec3   pixel_delta_u;  // Offset to pixel to the right
    vec3   pixel_delta_v;  // Offset to pixel below

    void initialize() {
        image_height = int(image_width / aspect_ratio);
        image_height = (image_height < 1) ? 1 : image_height;

        center = point3(0, 0, 0);

        // Determine viewport dimensions.
        auto focal_length = 1.0;
        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.
        pixel_delta_u = viewport_u / image_width;
        pixel_delta_v = viewport_v / image_height;

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

#### render()

Also move the render loop from main() to the camera class

```cpp
public:
    double aspect_ratio = 1.0;  // Ratio of image width over height
    int    image_width  = 100;  // Rendered image width in pixel count

    void render(const hittable& world) {
        initialize();

        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++) {
                auto pixel_center = pixel00_loc + (i * pixel_delta_u) + (j * pixel_delta_v);
                auto ray_direction = pixel_center - center;
                ray r(center, ray_direction);

                color pixel_color = ray_color(r, world);
                write_color(std::cout, pixel_color);
            }
        }

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

### Reduce main.cpp

The following is the reduced main after using the camera class

```cpp
#include "rtweekend.h"

// ================================
#include "camera.h"
// ================================

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


int main() {

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

    camera cam;
    cam.aspect_ratio = 16.0 / 9.0;
    cam.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));
    // =====================================================

    cam.render(world);

}
```

### Build and run the Program

You should be able to build your program successfully and run it as follows:

```
./ray01.exe > image6.ppm
```

You should see the same rendering as in T2

<figure><img src="https://3464970502-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3JUKGJZ67JX02QZdPhsy%2Fuploads%2F4wzFHTh7pmPOS9MNiQGl%2F142f10d1-c28e-4fa5-a6b1-648dcb0784f5.png?alt=media&#x26;token=f161ddcf-7b6b-46c1-a9f6-6953f442bbb8" alt="" width="479"><figcaption></figcaption></figure>
