-
Notifications
You must be signed in to change notification settings - Fork 0
/
sphere.t
55 lines (43 loc) · 1.44 KB
/
sphere.t
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
50
51
52
53
54
55
class sphere
inherit hittable
import vec3, dot, vsub, vfdiv
export initialize
var center : ^vec3
var radius : real
procedure initialize(cent : ^vec3, rad : real)
center := cent
radius := max(0, rad)
end initialize
body function hit(r : ^ray, ray_t : ^interval, rec : ^hit_record) : boolean
var oc : ^vec3 := vsub(center, r -> origin)
var a : real := r -> direction -> len_squared
var h : real := dot(r -> direction, oc)
var c : real := (oc -> len_squared) - (radius * radius)
var discriminant : real := (h * h) - (a*c)
if (discriminant < 0) then
free oc
result false
end if
var sqrtd : real := sqrt(discriminant)
var root : real := (h - sqrtd) / a
if not ray_t -> surrounds(root) then
root := (h + sqrtd) / a
if not ray_t -> surrounds(root) then
free oc
result false
end if
end if
rec -> sett(root)
rec -> setp(r -> at(rec -> t))
var outward_normal : ^vec3 := vfdiv(vsub(rec -> p, center), radius)
rec -> set_face_normal(r, outward_normal)
free oc
result true
end hit
end sphere
function sinit(center : ^vec3, radius : real) : ^sphere
var s : ^sphere
new s
s -> initialize(center, radius)
result s
end sinit