Add function to calculate sphere normal vector on given point on the sphere.
This commit is contained in:
@@ -27,6 +27,8 @@ public:
|
|||||||
Object();
|
Object();
|
||||||
|
|
||||||
virtual Intersect intersect(Ray r);
|
virtual Intersect intersect(Ray r);
|
||||||
|
virtual Tuple normalAt(Tuple point);
|
||||||
|
|
||||||
void setTransform(Matrix transform);
|
void setTransform(Matrix transform);
|
||||||
Ray transform(Ray r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); };
|
Ray transform(Ray r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); };
|
||||||
Ray invTransform(Ray r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); };
|
Ray invTransform(Ray r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); };
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class Sphere : public Object
|
|||||||
public:
|
public:
|
||||||
/* All sphere are at (0, 0, 0) and radius 1 in the object space */
|
/* All sphere are at (0, 0, 0) and radius 1 in the object space */
|
||||||
virtual Intersect intersect(Ray r);
|
virtual Intersect intersect(Ray r);
|
||||||
|
virtual Tuple normalAt(Tuple point);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //DORAYME_SPHERE_H
|
#endif //DORAYME_SPHERE_H
|
||||||
|
|||||||
@@ -24,6 +24,11 @@ Intersect Object::intersect(Ray r)
|
|||||||
return Intersect();
|
return Intersect();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Tuple Object::normalAt(Tuple point)
|
||||||
|
{
|
||||||
|
return Vector(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void Object::setTransform(Matrix transform)
|
void Object::setTransform(Matrix transform)
|
||||||
{
|
{
|
||||||
this->transformMatrix = transform;
|
this->transformMatrix = transform;
|
||||||
|
|||||||
@@ -36,3 +36,15 @@ Intersect Sphere::intersect(Ray r)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tuple Sphere::normalAt(Tuple point)
|
||||||
|
{
|
||||||
|
Tuple object_point = this->inverseTransform * point;
|
||||||
|
Tuple object_normal = (object_point - Point(0, 0, 0)).normalise();
|
||||||
|
Tuple world_normal = this->inverseTransform.transpose() * object_normal;
|
||||||
|
|
||||||
|
/* W may get wrong, so hack it. This is perfectly normal as we are using a 4x4 matrix instead of a 3x3 */
|
||||||
|
world_normal.w = 0;
|
||||||
|
|
||||||
|
return world_normal.normalise();
|
||||||
|
}
|
||||||
@@ -106,3 +106,75 @@ TEST(SphereTest, Intersecting_a_translated_sphere_with_a_ray)
|
|||||||
|
|
||||||
ASSERT_EQ(xs.count(), 0);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SphereTest, The_normal_on_a_sphere_at_a_point_on_the_X_axis)
|
||||||
|
{
|
||||||
|
Sphere s = Sphere();
|
||||||
|
Tuple n = s.normalAt(Point(1, 0, 0));
|
||||||
|
|
||||||
|
ASSERT_EQ(n, Vector(1, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SphereTest, The_normal_on_a_sphere_at_a_point_on_the_Y_axis)
|
||||||
|
{
|
||||||
|
Sphere s = Sphere();
|
||||||
|
Tuple n = s.normalAt(Point(0, 1, 0));
|
||||||
|
|
||||||
|
ASSERT_EQ(n, Vector(0, 1, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SphereTest, The_normal_on_a_sphere_at_a_point_on_the_Z_axis)
|
||||||
|
{
|
||||||
|
Sphere s = Sphere();
|
||||||
|
Tuple n = s.normalAt(Point(0, 0, 1));
|
||||||
|
|
||||||
|
ASSERT_EQ(n, Vector(0, 0, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SphereTest, The_normal_on_a_sphere_at_a_nonaxial_point)
|
||||||
|
{
|
||||||
|
Sphere s = Sphere();
|
||||||
|
Tuple n = s.normalAt(Point(sqrt(3)/3, sqrt(3)/3, sqrt(3)/3));
|
||||||
|
|
||||||
|
ASSERT_EQ(n, Vector(sqrt(3)/3, sqrt(3)/3, sqrt(3)/3));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SphereTest, The_normal_is_a_normalise_vector)
|
||||||
|
{
|
||||||
|
Sphere s = Sphere();
|
||||||
|
Tuple n = s.normalAt(Point(sqrt(3)/3, sqrt(3)/3, sqrt(3)/3));
|
||||||
|
|
||||||
|
ASSERT_EQ(n, n.normalise());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SphereTest, Computing_the_normal_on_a_translated_sphere)
|
||||||
|
{
|
||||||
|
Sphere s = Sphere();
|
||||||
|
|
||||||
|
s.setTransform(translation(0, 1, 0));
|
||||||
|
|
||||||
|
Tuple n = s.normalAt(Point(0, 1.70711, -0.70711));
|
||||||
|
|
||||||
|
set_equal_precision(0.0001);
|
||||||
|
|
||||||
|
ASSERT_EQ(n, Vector(0, 0.70711, -0.70711));
|
||||||
|
|
||||||
|
/* Revert to default */
|
||||||
|
set_equal_precision(FLT_EPSILON);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(SphereTest, Computing_the_normal_on_a_tranformed_sphere)
|
||||||
|
{
|
||||||
|
Sphere s = Sphere();
|
||||||
|
|
||||||
|
s.setTransform(scaling(1, 0.5, 1) * rotation_z(M_PI / 5));
|
||||||
|
|
||||||
|
Tuple n = s.normalAt(Point(0, sqrt(2)/2, -sqrt(2)/2));
|
||||||
|
|
||||||
|
set_equal_precision(0.0001);
|
||||||
|
|
||||||
|
ASSERT_EQ(n, Vector(0, 0.97014, -0.24254));
|
||||||
|
|
||||||
|
/* Revert to default */
|
||||||
|
set_equal_precision(FLT_EPSILON);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user