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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
class Vec3
def initialize(x = 0, y = 0, z = 0)
@x = x.to_f
@y = y.to_f
@z = z.to_f
end
attr_reader :x, :y, :z
def +(oth)
self.class.new(@x + oth.x, @y + oth.y, @z + oth.z)
end
def -@
self.class.new(-@x, -@y, -@z)
end
def -(oth)
self + -oth
end
def *(oth)
if oth.is_a?(Vec3)
self.class.new(@x * oth.x, @y * oth.y, @z * oth.z)
else
self.class.new(@x * oth, @y * oth, @z * oth)
end
end
def /(oth)
self * (1.0 / oth)
end
def dot(oth)
v = self * oth
v.x + v.y + v.z
end
def cross(oth)
self.class.new(
@y * oth.z - @z * oth.y,
@z * oth.x - @x * oth.z,
@x * oth.y - @y * oth.x
)
end
def mag_sqr
@x ** 2 + @y ** 2 + @z ** 2
end
def mag
mag_sqr ** 0.5
end
def unit
self / mag
end
def to_s
"{#{@x}, #{@y}, #{@z}}"
end
end
class Point < Vec3; end
class Colour < Vec3
def r; @x; end
def g; @y; end
def b; @z; end
def to_ppm
"%3d %3d %3d" % [(r * 255.999).to_i, (g * 255.999).to_i, (b * 255.999).to_i]
end
end
|