-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsphere.go
More file actions
46 lines (38 loc) · 1 KB
/
sphere.go
File metadata and controls
46 lines (38 loc) · 1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package main
import "math"
func NewSphere(center Vec3, radius float64, material Material) Sphere {
return Sphere{center: center, radius: radius, material: material}
}
type Sphere struct {
center Vec3
radius float64
material Material
}
func (s Sphere) Hit(ray *Ray, tMin, tMax float64) (bool, *HitRecord) {
oc := ray.origin.Sub(s.center)
a := ray.direction.Dot(ray.direction)
halfB := oc.Dot(ray.direction)
c := oc.Dot(oc) - s.radius*s.radius
discriminant := halfB*halfB - a*c
if discriminant < 0 {
return false, nil
}
sqrtd := math.Sqrt(discriminant)
// Find the nearest root that lies in the acceptable range.
root := (-halfB - sqrtd) / a
if root < tMin || tMax < root {
root = (-halfB + sqrtd) / a
if root < tMin || tMax < root {
return false, nil
}
}
point := ray.At(root)
record := HitRecord{
t: root,
point: point,
material: s.material,
}
outwardNormal := point.Sub(s.center).ScalarDiv(s.radius)
record.SetFaceNormal(ray, outwardNormal)
return true, &record
}