Преглед изворни кода

Add the hit function to get the closest non negative hit, and add some mecanisme to test that properly and report when no valid hit occur.

Godzil пре 4 година
родитељ
комит
c4418683c6
4 измењених фајлова са 99 додато и 1 уклоњено
  1. 1 0
      source/include/intersect.h
  2. 3 0
      source/include/intersection.h
  3. 25 1
      source/intersect.cpp
  4. 70 0
      tests/intersect_test.cpp

+ 1 - 0
source/include/intersect.h

@@ -23,6 +23,7 @@ public:
     void add(Intersection i);
     int count() { return this->num; };
     Intersection operator[](const int p) { return this->list[p]; }
+    Intersection hit();
 };
 
 #endif //DORAYME_INTERSECT_H

+ 3 - 0
source/include/intersection.h

@@ -21,6 +21,9 @@ public:
 
 public:
     Intersection(double t, Object *object) : t(t), object(object) { };
+    bool nothing() { return (this->object == nullptr); };
+
+    bool operator==(const Intersection &b) const { return ((this->t == b.t) && (this->object == b.object)); };
 };
 
 #endif //DORAYME_INTERSECTION_H

+ 25 - 1
source/intersect.cpp

@@ -7,9 +7,11 @@
  *
  */
 #include <stdlib.h>
-
+#include <math_helper.h>
 #include <intersect.h>
 
+#include <float.h>
+
 #define MIN_ALLOC (2)
 
 Intersect::Intersect()
@@ -27,4 +29,26 @@ void Intersect::add(Intersection i)
         this->list = (Intersection *)realloc(this->list, sizeof(Object *) * this->allocated);
     }
     this->list[this->num++] = i;
+}
+
+Intersection Intersect::hit()
+{
+    int i;
+    double minHit = DBL_MAX;
+    uint32_t curHit = -1;
+    for(i = 0; i < this->num; i++)
+    {
+        if ((this->list[i].t >= 0) && (this->list[i].t < minHit))
+        {
+            curHit = i;
+            minHit = this->list[i].t;
+        }
+    }
+
+    if (curHit == -1)
+    {
+        return Intersection(0, nullptr);
+    }
+
+    return this->list[curHit];
 }

+ 70 - 0
tests/intersect_test.cpp

@@ -59,4 +59,74 @@ TEST(IntersectTest, Intersect_sets_the_object_on_the_intersection)
     ASSERT_EQ(xs.count(), 2);
     ASSERT_EQ(xs[0].object, (Object *)&s);
     ASSERT_EQ(xs[1].object, (Object *)&s);
+}
+
+TEST(IntersectTest, The_hit_when_all_intersection_have_positive_t)
+{
+    Sphere s = Sphere();
+    Intersect xs = Intersect();
+
+    Intersection i1 = Intersection(1, &s);
+    Intersection i2 = Intersection(2, &s);
+
+    xs.add(i1);
+    xs.add(i2);
+
+    Intersection i = xs.hit();
+
+    ASSERT_EQ(i, i1);
+}
+
+TEST(IntersectTest, The_hit_when_some_intersection_have_negative_t)
+{
+    Sphere s = Sphere();
+    Intersect xs = Intersect();
+
+    Intersection i1 = Intersection(-1, &s);
+    Intersection i2 = Intersection(2, &s);
+    Intersection i3 = Intersection(12, &s);
+
+    xs.add(i1);
+    xs.add(i2);
+    xs.add(i3);
+
+    Intersection i = xs.hit();
+
+    ASSERT_EQ(i, i2);
+}
+
+TEST(IntersectTest, The_hit_when_all_intersection_have_negative_t)
+{
+    Sphere s = Sphere();
+    Intersect xs = Intersect();
+
+    Intersection i1 = Intersection(-2, &s);
+    Intersection i2 = Intersection(-1, &s);
+
+    xs.add(i1);
+    xs.add(i2);
+
+    Intersection i = xs.hit();
+
+    ASSERT_TRUE(i.nothing());
+}
+
+TEST(IntersectTest, The_hit_is_always_the_lowest_nonnegative_intersection)
+{
+    Sphere s = Sphere();
+    Intersect xs = Intersect();
+
+    Intersection i1 = Intersection(5, &s);
+    Intersection i2 = Intersection(7, &s);
+    Intersection i3 = Intersection(-3, &s);
+    Intersection i4 = Intersection(2, &s);
+
+    xs.add(i1);
+    xs.add(i2);
+    xs.add(i3);
+    xs.add(i4);
+
+    Intersection i = xs.hit();
+
+    ASSERT_EQ(i, i4);
 }