Class: Geom::Vector

Inherits:
Object
  • Object
show all
Defined in:
lib/geom/vector.rb

Overview

Vector defined by coordinates x, y, z

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Vector

Returns a new instance of Vector.



6
7
8
9
10
11
12
13
14
# File 'lib/geom/vector.rb', line 6

def initialize(*args)
  if args.size == 2
    @x = args[1].x.to_f - args[0].x.to_f
    @y = args[1].y.to_f - args[0].y.to_f
    @z = args[1].z.to_f - args[0].z.to_f
  else
    @x, @y, @z = args.flatten
  end
end

Instance Attribute Details

#xObject

Returns the value of attribute x.



4
5
6
# File 'lib/geom/vector.rb', line 4

def x
  @x
end

#yObject

Returns the value of attribute y.



4
5
6
# File 'lib/geom/vector.rb', line 4

def y
  @y
end

#zObject

Returns the value of attribute z.



4
5
6
# File 'lib/geom/vector.rb', line 4

def z
  @z
end

Class Method Details

.average(vectors) ⇒ Object



145
146
147
148
# File 'lib/geom/vector.rb', line 145

def self.average(vectors)
  num = vectors.size.to_f
  Vector.sum(vectors).scale(1/num)
end

.sum(vectors) ⇒ Object



150
151
152
153
154
155
156
157
158
# File 'lib/geom/vector.rb', line 150

def self.sum(vectors)
  tx, ty, tz = 0, 0, 0
  vectors.each do |vector|
    tx += vector.x
    ty += vector.y
    tz += vector.z
  end
  Vector.new(tx, ty, tz)
end

Instance Method Details

#*(scale) ⇒ Object Also known as: scale



24
25
26
# File 'lib/geom/vector.rb', line 24

def *(scale)
  Vector.new(@x * scale, @y * scale, @z * scale)
end

#**(power) ⇒ Object



42
43
44
# File 'lib/geom/vector.rb', line 42

def **(power)
  Vector.new(@x ** power, @y ** power, @z ** power)
end

#+(vector) ⇒ Object



20
21
22
# File 'lib/geom/vector.rb', line 20

def +(vector)
  Vector.new(@x + vector.x, @y + vector.y, @z + vector.z)
end

#-(vector) ⇒ Object



16
17
18
# File 'lib/geom/vector.rb', line 16

def -(vector)
  Vector.new(@x - vector.x, @y - vector.y, @z - vector.z)
end

#/(scale) ⇒ Object



46
47
48
# File 'lib/geom/vector.rb', line 46

def /(scale)
  self * (1.0/scale)
end

#==(vector) ⇒ Object Also known as: eql?



28
29
30
31
32
# File 'lib/geom/vector.rb', line 28

def ==(vector)
  (@x - vector.x).abs < TOLERANCE &&
  (@y - vector.y).abs < TOLERANCE &&
  (@z - vector.z).abs < TOLERANCE
end

#angle_between(vector) ⇒ Object



100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/geom/vector.rb', line 100

def angle_between(vector)
  # One of the vectors is a zero vector
  return nil if ((vector.length == 0) || (self.length == 0))

  dot = self.dot(vector)
  val = dot / (self.length * vector.length)

  if (val > 1.0)
    # Would result in NaN
    0.0
  else
    Math.acos(val)
  end
end

#cross(vector) ⇒ Object



54
55
56
57
58
# File 'lib/geom/vector.rb', line 54

def cross(vector)
  Vector.new(@y * vector.z - @z * vector.y,
  @z * vector.x - @x * vector.z,
  @x * vector.y - @y * vector.x)
end

#dot(vector) ⇒ Object



50
51
52
# File 'lib/geom/vector.rb', line 50

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

#hashObject



36
37
38
# File 'lib/geom/vector.rb', line 36

def hash
  (@x.to_int ^ @y.to_int ^ @z.to_int)
end

#lengthObject



68
69
70
# File 'lib/geom/vector.rb', line 68

def length
  Math.sqrt(self.dot(self))
end

#parallel?(vector) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
135
# File 'lib/geom/vector.rb', line 132

def parallel?(vector)
  angle = self.angle_between(vector)
  ((angle - Math::PI).abs < TOLERANCE) || (angle.abs < TOLERANCE)
end

#reverseObject



64
65
66
# File 'lib/geom/vector.rb', line 64

def reverse
  Vector.new(-@x, -@y, -@z)
end

#rotate(ref_vector, angle) ⇒ Object



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
# File 'lib/geom/vector.rb', line 72

def rotate(ref_vector, angle)
  r = [[0,0,0],[0,0,0],[0,0,0]]
  c = Math.cos(angle)
  s = Math.sin(angle)

  unit_ref_vector = ref_vector.unitize

  ax = unit_ref_vector.x
  ay = unit_ref_vector.y
  az = unit_ref_vector.z

  r[0][0] = (c + ((1 - c) * (ax * ax)))
  r[0][1] = (((1 - c) * (ax * ay)) - (s * az))
  r[0][2] = (((1 - c) * (ax * az)) + (s * ay))
  r[1][0] = (((1 - c) * (ax * ay)) + (s * az))
  r[1][1] = (c + ((1 - c) * (ay * ay)))
  r[1][2] = (((1 - c) * (ay * az)) - (s * ax))
  r[2][0] = (((1 - c) * (ax * az)) - (s * ay))
  r[2][1] = (((1 - c) * (ay * az)) + (s * ax))
  r[2][2] = (c + ((1 - c) * (az * az)))

  vx = ((r[0][0] * @x) + ((r[0][1] * @y) + (r[0][2] * @z)))
  vy = ((r[1][0] * @x) + ((r[1][1] * @y) + (r[1][2] * @z)))
  vz = ((r[2][0] * @x) + ((r[2][1] * @y) + (r[2][2] * @z)))

  Vector.new(vx, vy, vz)
end

#same_direction?(vector) ⇒ Boolean

If dot product > 0, angle is acute and vectors are the same direction If dot product < 0, angle is obtuse and vectors are in opposite direction If dot product = 0, vectors are orthogonal, including if one is zero vector (taken as same direction)

Returns:

  • (Boolean)


127
128
129
130
# File 'lib/geom/vector.rb', line 127

def same_direction?(vector)
  dotp = self.dot(vector);
  dotp > 0
end

#to_aObject



168
169
170
# File 'lib/geom/vector.rb', line 168

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

#to_pointObject



160
161
162
# File 'lib/geom/vector.rb', line 160

def to_point
  Point.new(@x,@y,@z)
end

#to_sObject



164
165
166
# File 'lib/geom/vector.rb', line 164

def to_s
  "Vector(%.3f,%.3f,%.3f)" % [@x, @y, @z]
end

#transform(rectangular_coordinate_system) ⇒ Object



116
117
118
119
120
121
122
# File 'lib/geom/vector.rb', line 116

def transform(rectangular_coordinate_system)
  m = Transformation.new(rectangular_coordinate_system).matrix
  tx = m[0,0] * @x + m[0,1] * @y + m[0,2] * @z + m[0,3] * 1.0
  ty = m[1,0] * @x + m[1,1] * @y + m[1,2] * @z + m[1,3] * 1.0
  tz = m[2,0] * @x + m[2,1] * @y + m[2,2] * @z + m[2,3] * 1.0
  Vector.new(tx, ty, tz)
end

#unitity?Boolean

Returns:

  • (Boolean)


141
142
143
# File 'lib/geom/vector.rb', line 141

def unitity?
  self.x == 1.0 && self.x == 1.0 && self.z == 1.0
end

#unitizeObject



60
61
62
# File 'lib/geom/vector.rb', line 60

def unitize
  self / self.length
end

#zero?Boolean

Returns:

  • (Boolean)


137
138
139
# File 'lib/geom/vector.rb', line 137

def zero?
  self.length <= 0.0
end