Class: Mageo::Vector3D

Inherits:
Vector
  • Object
show all
Defined in:
lib/mageo/vector3d.rb

Overview

Vector class specialized for vectors in a three-dimensional Cartesian space. This class provide exterior_product method and others, which is not included in native Vector class. This class is constructed under the assumption in the Cartesian coordinate. If you want to be in an internal coordinate, you can use Math/Mageo::Vector3DInternal.rb .

Memo:

Mageo::Vector3DInternal との対比として、Vector3DCartesian という名前にすることも考えたが、
長くなるし、普通直交座標で考えるよね、と。

インスタンス生成の時点で要素数をチェックし、要素の追加削除を禁止しているので
要素数は常に3であることが保証されている。

Direct Known Subclasses

Vector3DInternal

Defined Under Namespace

Classes: RangeError, TypeError, ZeroOperation

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Vector

#floor, #to_p2d, #to_v3d, #unit_vector

Class Method Details

.[](*args) ⇒ Object

Class methods

Raises:



44
45
46
47
# File 'lib/mageo/vector3d.rb', line 44

def self.[](*args)
  raise RangeError, "#{args}" unless args.size == 3
  super(*args)
end

.angle_degree(vec0, vec1) ⇒ Object

Get the angle with degree between self and other vectors.



92
93
94
95
96
97
98
99
# File 'lib/mageo/vector3d.rb', line 92

def self.angle_degree(vec0, vec1)
  [vec0, vec1].each_with_index do |vec, index|
    raise TypeError, "#{index}th vector: #{vec.inspect}" unless (vec.class == Mageo::Vector3D)
    raise ZeroOperation, "#{index}th vector: #{vec.inspect}" if (vec.r == 0.0)
  end

  self.angle_radian(vec0, vec1) * (180.0 / Math::PI)
end

.angle_radian(vec0, vec1) ⇒ Object

Get the angle with radian between self and other vectors.



82
83
84
85
86
87
88
89
# File 'lib/mageo/vector3d.rb', line 82

def self.angle_radian(vec0, vec1)
  [vec0, vec1].each_with_index do |vec, index|
    raise TypeError, "#{index}th vector: #{vec.inspect}" unless (vec.class == Mageo::Vector3D)
    raise ZeroOperation, "#{index}th vector: #{vec.inspect}" if (vec.r == 0.0)
  end

  Math::acos(vec0.inner_product(vec1) / (vec0.r * vec1.r))
end

.cross_productObject

Get the exterior product.



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/mageo/vector3d.rb', line 68

def self.exterior_product(vec0, vec1)
  [vec0, vec1].each_with_index do |vec, index|
    unless (vec.class == Mageo::Vector3D)
      raise TypeError, "Vector #{index}, #{vec.inspect}."
    end
  end

  bX = vec1[0];
  bY = vec1[1];
  bZ = vec1[2];

  cX = (vec0[1] * bZ - vec0[2] * bY);
  cY = (vec0[2] * bX - vec0[0] * bZ);
  cZ = (vec0[0] * bY - vec0[1] * bX);

  self[cX, cY, cZ]
end

.exterior_product(vec0, vec1) ⇒ Object

Get the exterior product.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/mageo/vector3d.rb', line 50

def self.exterior_product(vec0, vec1)
  [vec0, vec1].each_with_index do |vec, index|
    unless (vec.class == Mageo::Vector3D)
      raise TypeError, "Vector #{index}, #{vec.inspect}."
    end
  end

  bX = vec1[0];
  bY = vec1[1];
  bZ = vec1[2];

  cX = (vec0[1] * bZ - vec0[2] * bY);
  cY = (vec0[2] * bX - vec0[0] * bZ);
  cZ = (vec0[0] * bY - vec0[1] * bX);

  self[cX, cY, cZ]
end

.scalar_triple_product(vec0, vec1, vec2) ⇒ Object

Get the scalar triple product.



73
74
75
76
77
78
79
# File 'lib/mageo/vector3d.rb', line 73

def self.scalar_triple_product(vec0, vec1, vec2)
  [vec0, vec1, vec2].each_with_index do |vec, index|
    raise TypeError, "#{index}th vector: #{vec.inspect}" unless (vec.class == Mageo::Vector3D)
  end

  vec0.inner_product(vec1.exterior_product(vec2))
end

.vector_productObject

Get the exterior product.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/mageo/vector3d.rb', line 69

def self.exterior_product(vec0, vec1)
  [vec0, vec1].each_with_index do |vec, index|
    unless (vec.class == Mageo::Vector3D)
      raise TypeError, "Vector #{index}, #{vec.inspect}."
    end
  end

  bX = vec1[0];
  bY = vec1[1];
  bZ = vec1[2];

  cX = (vec0[1] * bZ - vec0[2] * bY);
  cY = (vec0[2] * bX - vec0[0] * bZ);
  cZ = (vec0[0] * bY - vec0[1] * bX);

  self[cX, cY, cZ]
end

Instance Method Details

#*(val) ⇒ Object

Vectorクラスで用意されているメソッドは Vectorクラスインスタンスを返すようになっているので、 Mageo::Vector3D クラスインスタンスを返すようにした * メソッド。 Argument ‘val’ must have :to_f method.

Raises:



142
143
144
145
146
# File 'lib/mageo/vector3d.rb', line 142

def *(val)
  #raise TypeError if (val.class != Float)
  raise TypeError unless val.methods.include?(:to_f)
  super(val.to_f).to_v3d
end

#+(vec) ⇒ Object

Vectorクラスで用意されているメソッドは Vectorクラスインスタンスを返すようになっているので、 Mageo::Vector3D クラスインスタンスを返すようにした + メソッド。



123
124
125
126
127
128
# File 'lib/mageo/vector3d.rb', line 123

def +(vec)
  unless (vec.class == Mageo::Vector3D)
    raise TypeError, "#{vec.inspect}."
  end
  super(vec).to_v3d
end

#-(vec) ⇒ Object

Vectorクラスで用意されているメソッドは Vectorクラスインスタンスを返すようになっているので、 Mageo::Vector3D クラスインスタンスを返すようにした - メソッド。



132
133
134
135
136
137
# File 'lib/mageo/vector3d.rb', line 132

def -(vec)
  unless (vec.class == Mageo::Vector3D)
    raise TypeError, "#{vec.inspect}."
  end
  super(vec).to_v3d
end

#[](index) ⇒ Object

Instance methods

Raises:



103
104
105
106
# File 'lib/mageo/vector3d.rb', line 103

def [](index)
  raise RangeError, "index: #{index}." if (index < 0 || 2 < index)
  super index
end

#[]=(index, val) ⇒ Object

Raises:



108
109
110
111
# File 'lib/mageo/vector3d.rb', line 108

def []=(index, val)
  raise RangeError, "index: #{index}." if (index < 0 || 2 < index)
  super index, val
end

#angle_degree(vec) ⇒ Object



189
190
191
# File 'lib/mageo/vector3d.rb', line 189

def angle_degree(vec)
  self.class.angle_degree(self, vec)
end

#angle_radian(vec) ⇒ Object



185
186
187
# File 'lib/mageo/vector3d.rb', line 185

def angle_radian(vec)
  self.class.angle_radian(self, vec)
end

#cloneObject

Vectorクラスで用意されているメソッドは Vectorクラスインスタンスを返すようになっているので、 Mageo::Vector3D クラスインスタンスを返すようにした clone メソッド。



150
151
152
# File 'lib/mageo/vector3d.rb', line 150

def clone
  super().to_v3d
end

#equal_in_delta?(other, tolerance = 0.0) ⇒ Boolean

ベクトルが等しいかチェック。 other として Mageo::Vector3D クラス以外のインスタンス渡すと Vector3D::TypeError。 両者の差分ベクトルの長さが tolerance 以下という判定になる。

Returns:

  • (Boolean)

Raises:



116
117
118
119
# File 'lib/mageo/vector3d.rb', line 116

def equal_in_delta?(other, tolerance = 0.0)
  raise TypeError if (other.class != Mageo::Vector3D)
  return (other - self).r <= tolerance
end

#exterior_product(vec) ⇒ Object Also known as: cross_product, vector_product

Get the exterior product.



175
176
177
# File 'lib/mageo/vector3d.rb', line 175

def exterior_product(vec)
  self.class.exterior_product(self, vec)
end

#internal_coordinates(axes) ⇒ Object

Convert to Mageo::Vector3DInternal. Non-destructive.

Raises:



155
156
157
158
159
160
# File 'lib/mageo/vector3d.rb', line 155

def internal_coordinates(axes)
  raise TypeError unless axes.is_a?(Mageo::Axes)

  axes = axes.to_a
  Mageo::Vector3DInternal[ *(Malge::SimultaneousEquations.cramer(axes.transpose, self)) ]
end

#rotate_axis(axis, radian) ⇒ Object

x, y, z 軸のいずれかで self を回転した座標を返す。非破壊的。 axis は 0, 1, 2 のいずれかで、それぞれ x, y, z軸を示す。 radian は回転する角度で、原点から軸の伸びる方向に対して右ねじ方向を正とする。 すなわち、軸の正の値の位置から原点を見たとき、左回りが正である。 e.g., y軸中心で回転し、z軸を x軸になるように変換。 self.rotate_axis(1, 0.5*PI)



234
235
236
237
238
# File 'lib/mageo/vector3d.rb', line 234

def rotate_axis(axis, radian)
  tmp = Marshal.load(Marshal.dump(self))
  tmp.rotate_axis!(axis, radian)
  tmp
end

#rotate_axis!(axis, radian) ⇒ Object

x, y, z 軸のいずれかで self を回転する。破壊的。 axis は 0, 1, 2 のいずれかで、それぞれ x, y, z軸を示す。 radian は回転する角度で、原点から軸の伸びる方向に対して右ねじ方向を正とする。 すなわち、軸の正の値の位置から原点を見たとき、左回りが正である。 e.g., y軸中心で回転し、z軸を x軸になるように変換。 self.rotate_axis!(1, 0.5*PI)

Raises:



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/mageo/vector3d.rb', line 212

def rotate_axis!(axis, radian)
  raise RangeError, "Axis id is #{axis}." if (axis < 0 || 2 < axis)
  #axis1, axis2 はそれぞれ、 x軸から見て y軸, z軸。y に対する z, x。z に対する x, y。
  axis1 = (axis + 1) % 3
  axis2 = (axis + 2) % 3

  tmp = Array.new(3)
  tmp[ axis  ] = self[ axis  ]
  tmp[ axis1 ] = Math::cos(radian) * self[ axis1 ] - Math::sin(radian) * self[ axis2 ]
  tmp[ axis2 ] = Math::sin(radian) * self[ axis1 ] + Math::cos(radian) * self[ axis2 ]
  tmp.to_v3d
  self[0] = tmp[0]
  self[1] = tmp[1]
  self[2] = tmp[2]
end

#scalar_triple_product(vec0, vec1) ⇒ Object



181
182
183
# File 'lib/mageo/vector3d.rb', line 181

def scalar_triple_product(vec0, vec1)
  self.class.scalar_triple_product(self, vec0, vec1)
end

#sizeObject

Return size, always 3.



170
171
172
# File 'lib/mageo/vector3d.rb', line 170

def size
  return 3
end

#to_p3dObject

3次元極座標への変換した Mageo::Polar3D インスタンスを返す。



194
195
196
197
198
199
200
201
202
203
204
# File 'lib/mageo/vector3d.rb', line 194

def to_p3d
  r = self.r
  if r == 0.0
    theta = 0.0
    phi = 0.0
  else
    theta = Mageo::Polar2D.minimum_radian(Math::acos(self[2] / r))
    phi = Vector[ self[0], self[1] ].to_p2d.theta
  end
  Mageo::Polar3D.new(r, theta, phi)
end

#to_v3diObject

Change the self.class to Vector3DInternal, Keeping the values of coordinates.



164
165
166
167
# File 'lib/mageo/vector3d.rb', line 164

def to_v3di
  axes = Mageo::Axes.new( [ [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0] ])
  internal_coordinates(axes)
end