-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathsphere.go
More file actions
49 lines (41 loc) · 1.12 KB
/
sphere.go
File metadata and controls
49 lines (41 loc) · 1.12 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
47
48
49
package main
import "math"
type Sphere struct {
center Point3
radius float64
material Material
}
// hit implements the hit interface for a Sphere
func (s Sphere) hit(r *Ray, tMin float64, tMax float64) (bool, *HitRecord) {
oc := r.Origin.Sub(s.center) // A-C
a := Dot(r.Direction, r.Direction) // dot(B, B)
b := Dot(oc, r.Direction) // dot(A-C, B)
c := Dot(oc, oc) - s.radius*s.radius // dot(A-C, A-C) - R*R
discriminant := b*b - a*c
if discriminant > 0 {
discriminantSquareRoot := math.Sqrt(discriminant)
temp := (-b - discriminantSquareRoot) / a
if temp < tMax && temp > tMin {
hitPoint := r.PointAt(temp)
hr := HitRecord{
t: temp,
p: hitPoint,
normal: hitPoint.Sub(s.center).Scale(1 / s.radius),
material: s.material,
}
return true, &hr
}
temp = (-b + discriminantSquareRoot) / a
if temp < tMax && temp > tMin {
hitPoint := r.PointAt(temp)
hr := HitRecord{
t: temp,
p: hitPoint,
normal: hitPoint.Sub(s.center).Scale(1 / s.radius),
material: s.material,
}
return true, &hr
}
}
return false, nil
}