Class: Mittsu::Vector3

Inherits:
Object
  • Object
show all
Defined in:
lib/mittsu/math/vector3.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x = 0, y = 0, z = 0) ⇒ Vector3

Returns a new instance of Vector3.



7
8
9
10
11
# File 'lib/mittsu/math/vector3.rb', line 7

def initialize(x = 0, y = 0, z = 0)
  @x = x.to_f
  @y = y.to_f
  @z = z.to_f
end

Instance Attribute Details

#xObject

Returns the value of attribute x.



5
6
7
# File 'lib/mittsu/math/vector3.rb', line 5

def x
  @x
end

#yObject

Returns the value of attribute y.



5
6
7
# File 'lib/mittsu/math/vector3.rb', line 5

def y
  @y
end

#zObject

Returns the value of attribute z.



5
6
7
# File 'lib/mittsu/math/vector3.rb', line 5

def z
  @z
end

Instance Method Details

#==(v) ⇒ Object



450
451
452
# File 'lib/mittsu/math/vector3.rb', line 450

def ==(v)
  ((v.x == @x) && (v.y == @y) && (v.z == @z))
end

#[](index) ⇒ Object

Raises:

  • (IndexError)


39
40
41
42
43
44
# File 'lib/mittsu/math/vector3.rb', line 39

def [](index)
  return @x if index == 0 || index == :x
  return @y if index == 1 || index == :y
  return @z if index == 2 || index == :z
  raise IndexError
end

#[]=(index, value) ⇒ Object

Raises:

  • (IndexError)


32
33
34
35
36
37
# File 'lib/mittsu/math/vector3.rb', line 32

def []=(index, value)
  return @x = value.to_f if index == 0 || index == :x
  return @y = value.to_f if index == 1 || index == :y
  return @z = value.to_f if index == 2 || index == :z
  raise IndexError
end

#add(v) ⇒ Object



53
54
55
56
57
58
# File 'lib/mittsu/math/vector3.rb', line 53

def add(v)
  @x += v.x
  @y += v.y
  @z += v.z
  self
end

#add_scalar(s) ⇒ Object



60
61
62
63
64
65
# File 'lib/mittsu/math/vector3.rb', line 60

def add_scalar(s)
  @x += s
  @y += s
  @z += s
  self
end

#add_vectors(a, b) ⇒ Object



67
68
69
70
71
72
# File 'lib/mittsu/math/vector3.rb', line 67

def add_vectors(a, b)
  @x = a.x + b.x
  @y = a.y + b.y
  @z = a.z + b.z
  self
end

#angle_to(v) ⇒ Object



401
402
403
404
405
406
# File 'lib/mittsu/math/vector3.rb', line 401

def angle_to(v)
  theta = self.dot(v) / (self.length * v.length)

  # clamp, to handle numerical problems
  Math.acos(Math.clamp(theta, -1.0, 1.0))
end

#apply_axis_angle(axis, angle) ⇒ Object



122
123
124
125
126
# File 'lib/mittsu/math/vector3.rb', line 122

def apply_axis_angle(axis, angle)
  quaternion = Mittsu::Quaternion.new
  self.apply_quaternion(quaternion.set_from_axis_angle(axis, angle))
  self
end

#apply_euler(euler) ⇒ Object



116
117
118
119
120
# File 'lib/mittsu/math/vector3.rb', line 116

def apply_euler(euler)
  quaternion = Mittsu::Quaternion.new
  self.apply_quaternion(quaternion.set_from_euler(euler))
  self
end

#apply_matrix3(m) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/mittsu/math/vector3.rb', line 128

def apply_matrix3(m)
  x = @x
  y = @y
  z = @z

  e = m.elements

  @x = e[0] * x + e[3] * y + e[6] * z
  @y = e[1] * x + e[4] * y + e[7] * z
  @z = e[2] * x + e[5] * y + e[8] * z

  self
end

#apply_matrix4(m) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/mittsu/math/vector3.rb', line 142

def apply_matrix4(m)
  # input: THREE.Matrix4 affine matrix

  xx, yy, zz = @x, @y, @z

  e = m.elements

  @x = e[0] * xx + e[4] * yy + e[8]  * zz + e[12]
  @y = e[1] * xx + e[5] * yy + e[9]  * zz + e[13]
  @z = e[2] * xx + e[6] * yy + e[10] * zz + e[14]

  self
end

#apply_projection(m) ⇒ Object



156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/mittsu/math/vector3.rb', line 156

def apply_projection(m)
  # input: THREE.Matrix4 projection matrix

  _x, _y, _z = @x, @y, @z

  e = m.elements
  d = 1.0 / (e[3] * _x + e[7] * _y + e[11] * _z + e[15]) # perspective divide

  @x = (e[0] * _x + e[4] * _y + e[8]  * _z + e[12]) * d
  @y = (e[1] * _x + e[5] * _y + e[9]  * _z + e[13]) * d
  @z = (e[2] * _x + e[6] * _y + e[10] * _z + e[14]) * d

  self
end

#apply_quaternion(q) ⇒ Object



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/mittsu/math/vector3.rb', line 171

def apply_quaternion(q)
  x = @x
  y = @y
  z = @z

  qx = q.x
  qy = q.y
  qz = q.z
  qw = q.w

  # calculate quat * vector

  ix =  qw * x + qy * z - qz * y
  iy =  qw * y + qz * x - qx * z
  iz =  qw * z + qx * y - qy * x
  iw = - qx * x - qy * y - qz * z

  # calculate result * inverse quat

  @x = ix * qw + iw * - qx + iy * - qz - iz * - qy
  @y = iy * qw + iw * - qy + iz * - qx - ix * - qz
  @z = iz * qw + iw * - qz + ix * - qy - iy * - qx

  self
end

#ceilObject



294
295
296
297
298
299
# File 'lib/mittsu/math/vector3.rb', line 294

def ceil
  @x = @x.ceil.to_f
  @y = @y.ceil.to_f
  @z = @z.ceil.to_f
  self
end

#clamp(min, max) ⇒ Object



273
274
275
276
277
278
# File 'lib/mittsu/math/vector3.rb', line 273

def clamp(min, max)
  @x = Math.clamp(@x, min.x, max.x)
  @y = Math.clamp(@y, min.y, max.y)
  @z = Math.clamp(@z, min.z, max.z)
  self
end

#clamp_scalar(min, max) ⇒ Object



280
281
282
283
284
285
# File 'lib/mittsu/math/vector3.rb', line 280

def clamp_scalar(min, max)
  @x = Math.clamp(@x, min, max)
  @y = Math.clamp(@y, min, max)
  @z = Math.clamp(@z, min, max)
  self
end

#cloneObject



483
484
485
# File 'lib/mittsu/math/vector3.rb', line 483

def clone
  Mittsu::Vector3.new(@x, @y, @z)
end

#copy(v) ⇒ Object



46
47
48
49
50
51
# File 'lib/mittsu/math/vector3.rb', line 46

def copy(v)
  @x = v.x
  @y = v.y
  @z = v.z
  self
end

#cross(v) ⇒ Object



362
363
364
365
366
367
368
# File 'lib/mittsu/math/vector3.rb', line 362

def cross(v)
  x, y, z = @x, @y, @z
  @x = y * v.z - z * v.y
  @y = z * v.x - x * v.z
  @z = x * v.y - y * v.x
  self
end

#cross_vectors(a, b) ⇒ Object



370
371
372
373
374
375
376
377
378
379
# File 'lib/mittsu/math/vector3.rb', line 370

def cross_vectors(a, b)
  ax, ay, az = a.x, a.y, a.z
  bx, by, bz = b.x, b.y, b.z

  @x = ay * bz - az * by
  @y = az * bx - ax * bz
  @z = ax * by - ay * bx

  self
end

#distance_to(v) ⇒ Object



408
409
410
# File 'lib/mittsu/math/vector3.rb', line 408

def distance_to(v)
  Math.sqrt(self.distance_to_squared(v))
end

#distance_to_squared(v) ⇒ Object



412
413
414
415
416
417
# File 'lib/mittsu/math/vector3.rb', line 412

def distance_to_squared(v)
  dx = @x - v.x
  dy = @y - v.y
  dz = @z - v.z
  dx * dx + dy * dy + dz * dz
end

#divide(v) ⇒ Object



226
227
228
229
230
231
# File 'lib/mittsu/math/vector3.rb', line 226

def divide(v)
  @x /= v.x
  @y /= v.y
  @z /= v.z
  self
end

#divide_scalar(scalar) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/mittsu/math/vector3.rb', line 233

def divide_scalar(scalar)
  if scalar != 0
    invScalar = 1.0 / scalar
    @x *= invScalar
    @y *= invScalar
    @z *= invScalar
  else
    @x = 0
    @y = 0
    @z = 0
  end
  self
end

#dot(v) ⇒ Object



322
323
324
# File 'lib/mittsu/math/vector3.rb', line 322

def dot(v)
  @x * v.x + @y * v.y + @z * v.z
end

#floorObject



287
288
289
290
291
292
# File 'lib/mittsu/math/vector3.rb', line 287

def floor
  @x = @x.floor.to_f
  @y = @y.floor.to_f
  @z = @z.floor.to_f
  self
end

#from_attribute(attribute, index, offse = 0) ⇒ Object



473
474
475
476
477
478
479
480
481
# File 'lib/mittsu/math/vector3.rb', line 473

def from_attribute(attribute, index, offse = 0)
  index = index * attribute.itemSize + offset

  @x = attribute.array[index]
  @y = attribute.array[index + 1]
  @z = attribute.array[index + 2]

  self
end

#fromArray(array, offset = 0) ⇒ Object



454
455
456
457
458
459
# File 'lib/mittsu/math/vector3.rb', line 454

def fromArray(array, offset = 0)
  @x = array[offset]
  @y = array[offset + 1]
  @z = array[offset + 2]
  self
end

#lengthObject



330
331
332
# File 'lib/mittsu/math/vector3.rb', line 330

def length
  Math.sqrt(length_sq)
end

#length_manhattanObject



334
335
336
# File 'lib/mittsu/math/vector3.rb', line 334

def length_manhattan
  @x.abs + @y.abs + @z.abs
end

#length_sqObject



326
327
328
# File 'lib/mittsu/math/vector3.rb', line 326

def length_sq
  self.dot(self)
end

#lerp(v, alpha) ⇒ Object



350
351
352
353
354
355
# File 'lib/mittsu/math/vector3.rb', line 350

def lerp(v, alpha)
  @x += (v.x - @x) * alpha
  @y += (v.y - @y) * alpha
  @z += (v.z - @z) * alpha
  self
end

#lerp_vectors(v1, v2, alpha) ⇒ Object



357
358
359
360
# File 'lib/mittsu/math/vector3.rb', line 357

def lerp_vectors(v1, v2, alpha)
  self.sub_vectors(v2, v1).multiply_scalar(alpha).add(v1)
  self
end

#max(v) ⇒ Object



260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/mittsu/math/vector3.rb', line 260

def max(v)
  if @x < v.x
    @x = v.x
  end
  if @y < v.y
    @y = v.y
  end
  if @z < v.z
    @z = v.z
  end
  self
end

#min(v) ⇒ Object



247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/mittsu/math/vector3.rb', line 247

def min(v)
  if @x > v.x
    @x = v.x
  end
  if @y > v.y
    @y = v.y
  end
  if @z > v.z
    @z = v.z
  end
  self
end

#multiply(v) ⇒ Object



95
96
97
98
99
100
# File 'lib/mittsu/math/vector3.rb', line 95

def multiply(v)
  @x *= v.x
  @y *= v.y
  @z *= v.z
  self
end

#multiply_scalar(scalar) ⇒ Object



102
103
104
105
106
107
# File 'lib/mittsu/math/vector3.rb', line 102

def multiply_scalar(scalar)
  @x *= scalar
  @y *= scalar
  @z *= scalar
  self
end

#multiply_vectors(a, b) ⇒ Object



109
110
111
112
113
114
# File 'lib/mittsu/math/vector3.rb', line 109

def multiply_vectors(a, b)
  @x = a.x * b.x
  @y = a.y * b.y
  @z = a.z * b.z
  self
end

#negateObject



315
316
317
318
319
320
# File 'lib/mittsu/math/vector3.rb', line 315

def negate
  @x = - @x
  @y = - @y
  @z = - @z
  self
end

#normalizeObject



338
339
340
# File 'lib/mittsu/math/vector3.rb', line 338

def normalize
  self.divide_scalar(self.length)
end

#project(camera) ⇒ Object



197
198
199
200
201
# File 'lib/mittsu/math/vector3.rb', line 197

def project(camera)
  matrix = Mittsu::Matrix4.new
  matrix.multiply_matrices(camera.projection_matrix, matrix.get_inverse(camera.matrix_world))
  self.apply_projection(matrix)
end

#project_on_plane(plane_normal) ⇒ Object



388
389
390
391
392
# File 'lib/mittsu/math/vector3.rb', line 388

def project_on_plane(plane_normal)
  v1 = Mittsu::Vector3.new
  v1.copy(self).project_on_vector(plane_normal)
  self.sub(v1)
end

#project_on_vector(vector) ⇒ Object



381
382
383
384
385
386
# File 'lib/mittsu/math/vector3.rb', line 381

def project_on_vector(vector)
  v1 = Mittsu::Vector3.new
  v1.copy(vector).normalize
  dot = self.dot(v1)
  self.copy(v1).multiply_scalar(dot)
end

#reflect(normal) ⇒ Object



394
395
396
397
398
399
# File 'lib/mittsu/math/vector3.rb', line 394

def reflect(normal)
  # reflect incident vector off plane orthogonal to normal
  # normal is assumed to have unit length
  v1 = Mittsu::Vector3.new
  self.sub(v1.copy(normal).multiply_scalar(2.0 * self.dot(normal)))
end

#roundObject



301
302
303
304
305
306
# File 'lib/mittsu/math/vector3.rb', line 301

def round
  @x = @x.round.to_f
  @y = @y.round.to_f
  @z = @z.round.to_f
  self
end

#round_to_zeroObject



308
309
310
311
312
313
# File 'lib/mittsu/math/vector3.rb', line 308

def round_to_zero
  @x = (@x < 0) ? @x.ceil.to_f : @x.floor.to_f
  @y = (@y < 0) ? @y.ceil.to_f : @y.floor.to_f
  @z = (@z < 0) ? @z.ceil.to_f : @z.floor.to_f
  self
end

#set(x, y, z) ⇒ Object



25
26
27
28
29
30
# File 'lib/mittsu/math/vector3.rb', line 25

def set(x, y, z)
  @x = x.to_f
  @y = y.to_f
  @z = z.to_f
  self
end

#set_from_matrix_column(index, matrix) ⇒ Object



438
439
440
441
442
443
444
445
446
447
448
# File 'lib/mittsu/math/vector3.rb', line 438

def set_from_matrix_column(index, matrix)
  offset = index * 4

  me = matrix.elements

  @x = me[offset]
  @y = me[offset + 1]
  @z = me[offset + 2]

  self
end

#set_from_matrix_position(m) ⇒ Object



419
420
421
422
423
424
# File 'lib/mittsu/math/vector3.rb', line 419

def set_from_matrix_position(m)
  @x = m.elements[12]
  @y = m.elements[13]
  @z = m.elements[14]
  self
end

#set_from_matrix_scale(m) ⇒ Object



426
427
428
429
430
431
432
433
434
435
436
# File 'lib/mittsu/math/vector3.rb', line 426

def set_from_matrix_scale(m)
  sx = self.set(m.elements[0], m.elements[1], m.elements[ 2]).length
  sy = self.set(m.elements[4], m.elements[5], m.elements[ 6]).length
  sz = self.set(m.elements[8], m.elements[9], m.elements[10]).length

  @x = sx
  @y = sy
  @z = sz

  self
end

#set_length(l) ⇒ Object



342
343
344
345
346
347
348
# File 'lib/mittsu/math/vector3.rb', line 342

def set_length(l)
  old_length = self.length
  if old_length != 0 && l != old_length
    self.multiply_scalar(l / old_length)
  end
  self
end

#sub(v) ⇒ Object



74
75
76
77
78
79
# File 'lib/mittsu/math/vector3.rb', line 74

def sub(v)
  @x -= v.x
  @y -= v.y
  @z -= v.z
  self
end

#sub_scalar(s) ⇒ Object



81
82
83
84
85
86
# File 'lib/mittsu/math/vector3.rb', line 81

def sub_scalar(s)
  @x -= s
  @y -= s
  @z -= s
  self
end

#sub_vectors(a, b) ⇒ Object



88
89
90
91
92
93
# File 'lib/mittsu/math/vector3.rb', line 88

def sub_vectors(a, b)
  @x = a.x - b.x
  @y = a.y - b.y
  @z = a.z - b.z
  self
end

#to_aObject



469
470
471
# File 'lib/mittsu/math/vector3.rb', line 469

def to_a
  self.to_array
end

#to_array(array = [], offset = 0) ⇒ Object



461
462
463
464
465
466
467
# File 'lib/mittsu/math/vector3.rb', line 461

def to_array(array = [], offset = 0)
  array[offset] = @x
  array[offset + 1] = @y
  array[offset + 2] = @z

  array
end

#to_sObject



487
488
489
# File 'lib/mittsu/math/vector3.rb', line 487

def to_s
  "[#{x}, #{y}, #{z}]"
end

#transform_direction(m) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/mittsu/math/vector3.rb', line 209

def transform_direction(m)
  # input: THREE.Matrix4 affine matrix
  # vector interpreted as a direction

  x = @x, y = @y, z = @z

  e = m.elements

  @x = e[0] * x + e[4] * y + e[8]  * z
  @y = e[1] * x + e[5] * y + e[9]  * z
  @z = e[2] * x + e[6] * y + e[10] * z

  self.normalize

  self
end

#unproject(camera) ⇒ Object



203
204
205
206
207
# File 'lib/mittsu/math/vector3.rb', line 203

def unproject(camera)
  matrix = Mittsu::Matrix4.new
  matrix.multiply_matrices(camera.matrix_world, matrix.inverse(camera.projection_matrix))
  self.apply_projection(matrix)
end