summaryrefslogtreecommitdiffstats
path: root/qtruby/rubylib/examples/ruboids/ruboids/Point.rb
blob: 0331f7955794791b4bafdf6d7935ade810e9232d (plain)
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#
# Copyright (c) 2001 by Jim Menard <jimm@io.com>
#
# Released under the same license as Ruby. See
# http://www.ruby-lang.org/en/LICENSE.txt.
#

class Point

    attr_accessor :x, :y, :z

    # Return a new Point that is the midpoint on the line between two
    # points.
    def Point.midpoint(a, b)
	return Point.new((a.x + b.x) * 0.5, (a.y + b.y) * 0.5,
			   (a.z + b.z) * 0.5)
    end

    def initialize(x = 0, y = 0, z = 0)
	if x.kind_of?(Point)
	    @x = x.x
	    @y = x.y
	    @z = x.z
	else
	    @x = x
	    @y = y
	    @z = z
	end
    end

    ORIGIN = Point.new(0, 0, 0)

    def ==(point)
	return point.kind_of?(Point) &&
	    @x == point.x && @y == point.y && @z == point.z
    end

    # Normalize this point.
    def normalize!
	mag = @x * @x + @y * @y + @z * @z
	if mag != 1.0
	    mag = 1.0 / Math.sqrt(mag)
	    @x *= mag
	    @y *= mag
	    @z *= mag
	end
	return self
    end

    # Return a new point that is a normalized version of this point.
    def normalize
	return self.dup().normalize!()
    end

    # Return a new point that is the cross product of this point and another.
    # The cross product of two unit vectors is another vector that's at
    # right angles to the first two (for example, a surface normal).
    def crossProduct(p)
	return Point.new(@y * p.z - @z * p.y, @z * p.x - @x * p.z,
			 @x * p.y - @y * p.x)
    end

    # Return the (scalar) dot product of this vector and another.
    # The dot product of two vectors produces the cosine of the angle
    # between them, multiplied by the lengths of those vectors. (The dot
    # product of two normalized vectors equals cosine of the angle.)
    def dotProduct(p)
	return @x * p.x + @y * p.y + @z * p.z
    end

    # Return square of distance between this point and another.
    def squareOfDistanceTo(p)
	dx = p.x - @x
	dy = p.y - @y
	dz = p.z - @z
	return dx * dx + dy * dy + dz * dz
    end

    # Return distance between this point and another.
    def distanceTo(p)
	dx = p.x - @x
	dy = p.y - @y
	dz = p.z - @z
	return Math.sqrt(dx * dx + dy * dy + dz * dz)
    end

    def add(d)
	@x += d
	@y += d
	@z += d
	return self
    end

    def addPoint(p)
	@x += p.x
	@y += p.y
	@z += p.z
	return self
    end


    def subtract(d)
	@x -= d
	@y -= d
	@z -= d
	return self
    end

    def subtractPoint(p)
	@x -= p.x
	@y -= p.y
	@z -= p.z
	return self
    end


    def multiplyBy(d)
	@x *= d
	@y *= d
	@z *= d
	return self
    end

    def multiplyByPoint(p)
	@x *= p.x
	@y *= p.y
	@z *= p.z
	return self
    end

    def divideBy(d)
	@x = @x / d
	@y = @y / d
	@z = @z / d
	return self
    end

    def divideByPoint(p)
	@x = @x / p.x
	@y = @y / p.y
	@z = @z / p.z
	return self
    end

    def to_a
	return [@x, @y, @z]
    end

    def to_s
	return "Point<#{@x}, #{@y}, #{@z}>"
    end

end