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:



48
49
50
51
# File 'lib/mageo/vector3d.rb', line 48

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.



96
97
98
99
100
101
102
103
# File 'lib/mageo/vector3d.rb', line 96

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.



86
87
88
89
90
91
92
93
# File 'lib/mageo/vector3d.rb', line 86

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.



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

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.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/mageo/vector3d.rb', line 54

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.



77
78
79
80
81
82
83
# File 'lib/mageo/vector3d.rb', line 77

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.



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/mageo/vector3d.rb', line 73

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:



147
148
149
150
151
# File 'lib/mageo/vector3d.rb', line 147

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 クラスインスタンスを返すようにした + メソッド。



128
129
130
131
132
133
# File 'lib/mageo/vector3d.rb', line 128

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

#-(vec) ⇒ Object

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



137
138
139
140
141
142
# File 'lib/mageo/vector3d.rb', line 137

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

#[](index) ⇒ Object

Instance methods

Raises:



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

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

#[]=(index, val) ⇒ Object

Raises:



112
113
114
115
# File 'lib/mageo/vector3d.rb', line 112

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

#angle_degree(vec) ⇒ Object



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

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

#angle_radian(vec) ⇒ Object



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

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

#cloneObject

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



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

def clone
  super().to_v3d
end

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

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

Returns:

  • (Boolean)

Raises:



121
122
123
124
# File 'lib/mageo/vector3d.rb', line 121

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.



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

def exterior_product(vec)
  self.class.exterior_product(self, vec)
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)



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

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:



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

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



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

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

#sizeObject

Return size, always 3.



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

def size
  return 3
end

#to_p3dObject

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



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

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_v3di(axes) ⇒ Object

Convert to Mageo::Vector3DInternal. Non-destructive.

Raises:



160
161
162
163
164
165
166
# File 'lib/mageo/vector3d.rb', line 160

def to_v3di(axes)
  #pp axes.is_a?(Mageo::Axes)
  raise TypeError unless axes.is_a?(Mageo::Axes)

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