You can clone with
Minimum distance for ray intersection to be considered important.
This is due to limited numerical precision with floating point numbers. A ray could be reflected and then be immediately registered as intersecting with the object it just bounced off.
epsilon :: Scalar
epsilon = 0.1
Defines a mathematical sphere.
data Sphere = Sphere Vec3 Scalar deriving (Show, Read, Eq, Typeable)
instance Shape Sphere where
intersect ray@(Ray origin dir) ((Sphere center rad), material) = listToMaybe is
a = magSquared dir
b = 2 * ( dir `dot` (origin `sub` center))
c = (magSquared (origin `sub` center)) - rad^2
times = filter (> epsilon) (roots a b c)
normal_at_time t = normalize ((positionAtTime ray t) `sub` center)
intersection_at_time t = Intersection (normal_at_time t) (positionAtTime ray t) ray material
is = sortWith (\(t, _) -> t) $ map (\t -> (t,intersection_at_time t)) times
center (Sphere c _) = c