diff options
| -rw-r--r-- | color.go | 3 | ||||
| -rw-r--r-- | hitable.go | 24 |
2 files changed, 23 insertions, 4 deletions
@@ -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) @@ -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))} } |
