From e82e67681bf831a01bc6d5c96d9854489fd4b900 Mon Sep 17 00:00:00 2001
From: Yoel <s73017@beuth-hochschule.de>
Date: Sun, 30 Aug 2020 19:10:20 +0200
Subject: [PATCH] Sphere implementation added

---
 RayTracer/shape/Sphere.cpp | 44 ++++++++++++++++++++++++++++++++++++++
 RayTracer/shape/Sphere.h   | 15 +++++++++++++
 2 files changed, 59 insertions(+)
 create mode 100644 RayTracer/shape/Sphere.cpp
 create mode 100644 RayTracer/shape/Sphere.h

diff --git a/RayTracer/shape/Sphere.cpp b/RayTracer/shape/Sphere.cpp
new file mode 100644
index 0000000..8ad940f
--- /dev/null
+++ b/RayTracer/shape/Sphere.cpp
@@ -0,0 +1,44 @@
+#define _USE_MATH_DEFINES
+
+#include "Sphere.h"
+#include "math.h"
+
+namespace shapes {
+Sphere::Sphere(float radius, const std::shared_ptr<material::Material>& material)
+    : radius(radius)
+    , material(material)
+{
+}
+std::shared_ptr<cam::Hit> Sphere::intersect(const cam::Ray& r)
+{
+    util::Vec3 d = r.d;
+    util::Vec3 x0 = r.x0;
+    float a = util::dot(d, d);
+    float b = 2 * util::dot(x0, d);
+    float c = util::dot(x0, x0) - (radius * radius);
+    float discrim = b * b - 4 * a * c;
+
+    if (discrim >= 0) {
+        double t1 = (-b - sqrt(b * b - 4 * a * c)) / (2 * a);
+
+        if (r.in_range(t1)) {
+            util::Vec3 t1HitPoint = r(t1);
+            double theta = acos(t1HitPoint.y() / radius);
+            double phi = M_PI + atan2(t1HitPoint.x(), t1HitPoint.z());
+            return std::make_shared<cam::Hit>(cam::Hit(t1HitPoint, t1HitPoint, t1, material));
+        } else {
+            double t2 = (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
+            if (r.in_range(t2)) {
+                util::Vec3 t2HitPoint = r(t2);
+                double theta = acos(t2HitPoint.y() / radius);
+                double phi = M_PI + atan2(t2HitPoint.x(), t2HitPoint.z());
+                return std::make_shared<cam::Hit>(cam::Hit(t2HitPoint, t2HitPoint, t2, material));
+            } else {
+                return nullptr;
+            }
+        }
+    } else {
+        return nullptr;
+    }
+}
+}
diff --git a/RayTracer/shape/Sphere.h b/RayTracer/shape/Sphere.h
new file mode 100644
index 0000000..cd980d0
--- /dev/null
+++ b/RayTracer/shape/Sphere.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Shape.h"
+
+namespace shapes {
+class Sphere : public Shape {
+public:
+    Sphere(float radius, const std::shared_ptr<material::Material>& material);
+    std::shared_ptr<cam::Hit> intersect(const cam::Ray& r);
+
+private:
+    std::shared_ptr<material::Material> material;
+    const float radius;
+};
+}
-- 
GitLab