This repository has been archived on 2024-12-30. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
2024CG-project-render/lab1/Sphere.cpp
Tibo De Peuter d9cf26902e
Some checks failed
CMake / build (zip, zip, [self-hosted Linux], raytracing, ux) (push) Has been cancelled
CMake / build (zip, zip, [self-hosted Windows], Release/raytracing.exe, win) (push) Has been cancelled
chore: Cleanup
2024-10-25 17:50:44 +02:00

42 lines
1.4 KiB
C++

#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. */
const double a = ray.direction.dot(ray.direction);
const double b = ray.direction.dot(ray.origin - center);
const double c = (ray.origin - center).dot(ray.origin - center) - radius * radius;
const 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. */
const double under_root = b * b - a * c;
const 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;
}