Post by Paul on Dec 28, 2018 13:47:27 GMT
Hello. I can't get one test passing. All other tests that have been added before are passing though. The test is from Chapter 5, “Scenario: Intersecting a scaled sphere with a ray”. For the value of xs[0].t I get 0.1875, and for xs[1].t I get 0.4375 . So both values are exactly 16 times less than what's expected (values 3 and 7 respectively). After an hour of debugging I failed spotting where the bug is. I write my solutions in Elixir, so here's the code for "Sphere.intersect" function:
```
Intersecting a scaled sphere with a ray
iex> r = %Ray{origin: [0, 0, -5, Ray.Tuple.point_w], direction: [0, 0, 1, Ray.Tuple.vector_w]}
...> s = Sphere.create(Matrix.scaling([2, 2, 2]))
...> xs = Sphere.intersect(s, r)
...> Helpers.equal(xs[:count], 2)
...> Helpers.equal(xs[1].t, 3.0)
...> Helpers.equal(xs[1].t, 7.0, &Kernel.==/2, true)
true
"""
def intersect(sphere, ray) do
ray2 = Ray.transform(ray, sphere.transform |> Matrix.inverse) # ray2 is %Ray{direction: [0.0, 0.0, 0.5, 0.0], origin: [0.0, 0.0, -2.5, 1.0]}
sphere_to_ray = Ray.Tuple.sub(ray2.origin, [0, 0, 0, Ray.Tuple.point_w()])
a = Ray.Tuple.dot(ray2.direction, ray2.direction)
b = 2 * Ray.Tuple.dot(ray2.direction, sphere_to_ray)
c = Ray.Tuple.dot(sphere_to_ray, sphere_to_ray) - 1
discr = :math.pow(b, 2) - 4 * a * c
if discr < 0 do
Intersection.intersections({})
else
t1 = (-b - :math.sqrt(discr)) / 2 * a
t2 = (-b + :math.sqrt(discr)) / 2 * a
Intersection.intersections({
%Intersection{t: t1, object: sphere},
%Intersection{t: t2, object: sphere}
})
end
end
```
I think inverting transform matrix and then applying that transform to the ray is working fine. Probably there was a bug in the code of intersect added before, but it's hard to spot it. Please lmk if you need more code or some other info from me. Thank you very much!
```
Intersecting a scaled sphere with a ray
iex> r = %Ray{origin: [0, 0, -5, Ray.Tuple.point_w], direction: [0, 0, 1, Ray.Tuple.vector_w]}
...> s = Sphere.create(Matrix.scaling([2, 2, 2]))
...> xs = Sphere.intersect(s, r)
...> Helpers.equal(xs[:count], 2)
...> Helpers.equal(xs[1].t, 3.0)
...> Helpers.equal(xs[1].t, 7.0, &Kernel.==/2, true)
true
"""
def intersect(sphere, ray) do
ray2 = Ray.transform(ray, sphere.transform |> Matrix.inverse) # ray2 is %Ray{direction: [0.0, 0.0, 0.5, 0.0], origin: [0.0, 0.0, -2.5, 1.0]}
sphere_to_ray = Ray.Tuple.sub(ray2.origin, [0, 0, 0, Ray.Tuple.point_w()])
a = Ray.Tuple.dot(ray2.direction, ray2.direction)
b = 2 * Ray.Tuple.dot(ray2.direction, sphere_to_ray)
c = Ray.Tuple.dot(sphere_to_ray, sphere_to_ray) - 1
discr = :math.pow(b, 2) - 4 * a * c
if discr < 0 do
Intersection.intersections({})
else
t1 = (-b - :math.sqrt(discr)) / 2 * a
t2 = (-b + :math.sqrt(discr)) / 2 * a
Intersection.intersections({
%Intersection{t: t1, object: sphere},
%Intersection{t: t2, object: sphere}
})
end
end
```
I think inverting transform matrix and then applying that transform to the ray is working fine. Probably there was a bug in the code of intersect added before, but it's hard to spot it. Please lmk if you need more code or some other info from me. Thank you very much!