chore: Import Lab1
This commit is contained in:
parent
a04e6052d5
commit
2ddf32e172
7 changed files with 306 additions and 1 deletions
17
lab1/Plane.cpp
Normal file
17
lab1/Plane.cpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include "Plane.h"
|
||||
#include "Ray.h"
|
||||
|
||||
bool Plane::intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const
|
||||
{
|
||||
/* Based on
|
||||
* Computer Graphics, Chapter 4. Ray Tracing
|
||||
* Peter Lamber & Glenn Van Wallendael
|
||||
*/
|
||||
|
||||
t = -1;
|
||||
t = (point - ray.origin).dot(normal) / ray.direction.dot(normal);
|
||||
n = normal;
|
||||
|
||||
return min_t < t;
|
||||
}
|
42
lab1/Sphere.cpp
Normal file
42
lab1/Sphere.cpp
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include "Sphere.h"
|
||||
#include "Ray.h"
|
||||
bool Sphere::intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const
|
||||
{
|
||||
/* Based on
|
||||
* Fundamentals in Computer Graphics - Fourth Edition, Chapter 4.4.1. Ray-Sphere Intersection.
|
||||
* Steve Marschner & Peter Shirley
|
||||
*/
|
||||
|
||||
/* Intersection points occur when points on the ray satisfy the implicit equation. */
|
||||
|
||||
double a = ray.direction.dot(ray.direction);
|
||||
double b = ray.direction.dot(ray.origin - center);
|
||||
double c = (ray.origin - center).dot(ray.origin - center) - radius * radius;
|
||||
double discriminant = (2 * b) * (2 * b) - 4 * a * c;
|
||||
|
||||
/* If the discriminant is less than zero, the ray does not intersect with the sphere. */
|
||||
if (discriminant < 0) return false;
|
||||
|
||||
/* Calculate the first intersection t. */
|
||||
double under_root = b * b - a * c;
|
||||
double ta = (0 - b - sqrt(under_root)) / a;
|
||||
double tb = (0 - b + sqrt(under_root)) / a;
|
||||
/* Choose the smallest that is still larger than min_t. */
|
||||
if (ta < min_t && tb < min_t) {
|
||||
return false;
|
||||
} else if (ta < min_t) {
|
||||
t = tb;
|
||||
} else if (tb < min_t) {
|
||||
t = ta;
|
||||
} else {
|
||||
t = std::min(ta, tb);
|
||||
}
|
||||
|
||||
/* Calculate the surface normal vector at the point of intersection. */
|
||||
n = 2 * (ray.origin + t * ray.direction - center);
|
||||
/* Normalize the vector. */
|
||||
n = n.normalized();
|
||||
|
||||
return true;
|
||||
}
|
59
lab1/Triangle.cpp
Normal file
59
lab1/Triangle.cpp
Normal file
|
@ -0,0 +1,59 @@
|
|||
#include "Triangle.h"
|
||||
#include "Ray.h"
|
||||
#include <Eigen/Geometry> // hint
|
||||
|
||||
bool Triangle::intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const
|
||||
{
|
||||
/* Based on
|
||||
* Fundamentals in Computer Graphics - Fourth Edition, Chapter 4.4.2. Ray-Triangle Intersection.
|
||||
* Steve Marschner & Peter Shirley
|
||||
*/
|
||||
|
||||
Eigen::Vector3d a = std::get<0>(corners);
|
||||
Eigen::Vector3d b = std::get<1>(corners);
|
||||
Eigen::Vector3d c = std::get<2>(corners);
|
||||
Eigen::Vector3d e = ray.origin;
|
||||
Eigen::Vector3d d = ray.direction;
|
||||
|
||||
/* Using Cramer's rule. */
|
||||
|
||||
/* Calculate the determinant of A. */
|
||||
Eigen::Matrix3d A;
|
||||
A.col(0) = a - b;
|
||||
A.col(1) = a - c;
|
||||
A.col(2) = d;
|
||||
double determinant_A = A.determinant();
|
||||
|
||||
Eigen::Matrix3d t_matrix;
|
||||
t_matrix.col(0) = a - b;
|
||||
t_matrix.col(1) = a - c;
|
||||
t_matrix.col(2) = a - e;
|
||||
t = t_matrix.determinant() / determinant_A;
|
||||
|
||||
if (t < min_t) return false;
|
||||
|
||||
Eigen::Matrix3d gamma_matrix;
|
||||
gamma_matrix.col(0) = a - b;
|
||||
gamma_matrix.col(1) = a - e;
|
||||
gamma_matrix.col(2) = d;
|
||||
double gamma = gamma_matrix.determinant() / determinant_A;
|
||||
|
||||
if (gamma < 0 || gamma > 1) return false;
|
||||
|
||||
Eigen::Matrix3d beta_matrix;
|
||||
beta_matrix.col(0) = a - e;
|
||||
beta_matrix.col(1) = a - c;
|
||||
beta_matrix.col(2) = d;
|
||||
double beta = beta_matrix.determinant() / determinant_A;
|
||||
|
||||
if (beta < 0 || beta + gamma > 1) return false;
|
||||
|
||||
/* Calculate the surface normal vector using the cross product of two edges.
|
||||
* See https://en.wikipedia.org/wiki/Cross_product#Computational_geometry */
|
||||
Eigen::Vector3d edge1 = a - b;
|
||||
Eigen::Vector3d edge2 = a - c;
|
||||
n = edge1.cross(edge2).normalized(); /* Don't forget to normalize the vector. */
|
||||
|
||||
return true;
|
||||
}
|
11
lab1/TriangleSoup.cpp
Normal file
11
lab1/TriangleSoup.cpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "TriangleSoup.h"
|
||||
#include "Ray.h"
|
||||
// Hint
|
||||
#include "first_hit.h"
|
||||
|
||||
bool TriangleSoup::intersect(
|
||||
const Ray & ray, const double min_t, double & t, Eigen::Vector3d & n) const
|
||||
{
|
||||
int hit_id; /* Ignored. */
|
||||
return first_hit(ray, min_t, triangles, hit_id, t, n);
|
||||
}
|
33
lab1/first_hit.cpp
Normal file
33
lab1/first_hit.cpp
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "first_hit.h"
|
||||
|
||||
bool first_hit(
|
||||
const Ray & ray,
|
||||
const double min_t,
|
||||
const std::vector< std::shared_ptr<Object> > & objects,
|
||||
int & hit_id,
|
||||
double & t,
|
||||
Eigen::Vector3d & n)
|
||||
{
|
||||
bool hit = false;
|
||||
/* Initialize to a value that will never be used. */
|
||||
t = -1;
|
||||
/* Alternatively, use a max integer value, and remove the check t == -1. */
|
||||
|
||||
/* Store intermediate results that are not necessarily the first hit. */
|
||||
double t_temp;
|
||||
Eigen::Vector3d n_temp;
|
||||
|
||||
for (int i = 0; i < objects.size(); ++i) {
|
||||
if (objects[i]->intersect(ray, min_t, t_temp, n_temp)) {
|
||||
hit = true;
|
||||
if (t == -1 || t_temp < t) {
|
||||
hit_id = i;
|
||||
t = t_temp;
|
||||
n = n_temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hit;
|
||||
}
|
||||
|
24
lab1/viewing_ray.cpp
Normal file
24
lab1/viewing_ray.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "viewing_ray.h"
|
||||
|
||||
void viewing_ray(
|
||||
const Camera & camera,
|
||||
const int i,
|
||||
const int j,
|
||||
const int width,
|
||||
const int height,
|
||||
Ray & ray)
|
||||
{
|
||||
/* Based on
|
||||
* Fundamentals in Computer Graphics - Fourth Edition, Chapter 4.3.2 Perspective views.
|
||||
* Steve Marschner & Peter Shirley
|
||||
*/
|
||||
|
||||
/* Determine the direction of the ray, using the camera and pixel location. */
|
||||
double u = 0 - camera.width / 2 + camera.width * (j + 0.5) / width;
|
||||
double v = 0 - camera.height / 2 + camera.height * (i + 0.5) / height;
|
||||
|
||||
ray.origin = camera.e;
|
||||
/* NOTE I flipped the vertical axis of the pixels, because in computer graphics we assume the bottom left pixel
|
||||
* is (0,0), while traditional jpg assumes (0,0) to be the upper left pixel. */
|
||||
ray.direction = (0 - camera.d) * camera.w + u * camera.u - v * camera.v;
|
||||
}
|
Reference in a new issue