From 1008f463687a373f5c5d4024d25a09125b6c49ec Mon Sep 17 00:00:00 2001 From: Martin Lehoux Date: Sat, 4 Apr 2020 15:40:11 -0700 Subject: feat - Use HitRecord --- color.go | 3 ++- hitable.go | 24 +++++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/color.go b/color.go index 3514be6..dbcb47a 100644 --- a/color.go +++ b/color.go @@ -17,7 +17,8 @@ func LinearBlend(color1 Color, color2 Color, param float64) Color { } func RayColor(ray Ray, hitable Hitable) Color { - if hitable.Hit(ray) { + hit := hitable.Hit(ray) + if hit.time > 0 { return Color{1.0, 0.0, 0.0} } param := 0.5 * (ray.direction.Unit().y + 1) diff --git a/hitable.go b/hitable.go index a44026d..1443110 100644 --- a/hitable.go +++ b/hitable.go @@ -1,7 +1,16 @@ package main +import "math" + +type HitRecord struct { + time float64 + point Vec3D + normal Vec3D +} + type Hitable interface { - Hit(ray Ray) bool + Hit(ray Ray) HitRecord + Normal(point Vec3D) Vec3D } type Sphere struct { @@ -9,11 +18,20 @@ type Sphere struct { radius float64 } -func (sphere Sphere) Hit(ray Ray) bool { +func (sphere Sphere) Normal(point Vec3D) Vec3D { + return (SubVec3D(point, sphere.center)).Unit() +} + +func (sphere Sphere) Hit(ray Ray) HitRecord { oc := SubVec3D(ray.origin, sphere.center) a := DotProduct(ray.direction, ray.direction) b := 2.0 * DotProduct(oc, ray.direction) c := DotProduct(oc, oc) - sphere.radius*sphere.radius discriminant := b*b - 4*a*c - return discriminant > 0 + if discriminant < 0 { + return HitRecord{} + } + time := (-b - math.Sqrt(discriminant)) / 2.0 / a + point := ray.PointAt(time) + return HitRecord{time, point, SubVec3D(point, sphere.Normal(point))} } -- cgit v1.3