## New Primatives

This week I added two new primatives: Cylinder and Conical Frustum

### Cylinders

Cylinders are defined by two end points and a radius. Ray tracing can be broken into two parts:

1000 spp
• check to see if there is an intersection with the top/bottom (caps) of the cylinder
• check to see if there is an intersection with the trunk of the cylinder.
• If there are intersections, find the closest intersection

#### Checking to see if there is an intersection if there is an intersection with top/bottom

The top and bottom of a cylinder can be expressed as a plane

#### ` ax + by + cz + d = 0 `

Finding the intersection between the two involve finding the intersection between a ray and a plane.
Once you find the intersection with a ray and a plane, calculate the distance from the endpoint and the intersection. If the distance between the two points is less than or equal to the radius, then there is an intersection that occurs on the cap.

#### Checking to see if there is an intersection if there is an intersection with trunk

A cylinder is basically a circle that extends out in a 3rd dimension. First, translate the coordinates of the cylinder so that the two end points line on the same axis. Then apply the same tranformation matrix on the ray. At that point you can ignore the 3rd dimension and solve:

#### `( ray.start + ray.direct * t ) ^2 - r^2 = 0 `

This is a quadratic equation where you solve for t.

#### Determine the closest intersection

If there are multiple intersections, use the t with the smallest value to determine where the closest intersection is.

### Conical Frustums

1000 spp
Conical Frustums are similar to cylinders in that finding an intersection involves checking the caps and the trunk for an intersection. Checking the trunk is more involved for a conical frustum since unlike a cylinder the radius of the trunk changes at the height changes.

## More Path Tracing BRDFs

...Also this week I began exploring different BRDFs. Two in particular are basic reflections and refraction transfer functions.

### Reflections

1000 spp
Perfect reflection is a simple algorithm. Every ray which hits a surface has a component that run parallel to the normal and also a component that runs perpendicular to the normal. When a ray strikes a perfectly reflective surface, the parallel component reverses and the perpendicular component stays the same. This effect can be expressed as:
`Parallel_component = dot(ray.direction,normal) * normal               `
`Perpendicular_component = normal -  dot(ray.direction,normal) * normal`
Basically the direction of a ray is fliped across the surface. To change the direction of a ray, subtract the parallel component from the ray direction twice.
`Reflection = ray.direction - 2 * Parallel_component                `

### Refraction

I implemented refraction by using Snell's law. Snell's law expresses how light behaves when crossing the boundary of two different materials. With Snell's law, materials are given coefficients which desribe the ratio of the phase velocities in the different materials, which are refered to as indices of refraction.

Nell's law states that the ratio of the a ray's angle entering a material (relative to the material's surface normal) over the angle of the refracted ray is proportional to the ratio of their refractive indices.

```  sin(theta_incident)     N_incident
sin(theta_refracted)  = N_refracted```
This can be rearranged to find the angle of the refracted ray
```   sin(theta_refracted) = N_incident * sin(theta_incident)
N_refracted```
Futhermore
`   theta_refracted = sin^-1 ( N_incident/N_refracted * sin(theta_incident) )`
Using the following relationships:
`  sin(theta)^2 + cos(theta)^2  = 1`
`  dot ( ray_direction, Normal) = cos(theta)`
We can solve for sin(theta_incident)
`  sin(theta_incident) = sqrt ( 1 - ( dot ( ray_direction, Normal)^2 )`
and then solve for theta_refractive.
`   theta_refracted = sin^-1 ( N_incident/N_refracted * sqrt ( 1 - ( dot ( ray_direction, Normal)^2 ) )`

1000 spp
With theta_refracted, you have the angle of the refracted ray from the normal which can be used to generate an refraction vector. In the example image as a result of using a path tracer algorithm, there are caustics in the scene. Light traveling through the refractive sphere is bent towards similar directions thus become concentrated in areas behind the sphere which produces these lighting effects. I did not use a perfect refraction algorithm. With a sphere that is completely refractive, it may be difficult to see the outline of the sphere if it is infront of a smooth surface. In this example image, the refracted sphere is partially reflective so that the shape can be exposed.