Vector

数学Bのベクトルを復習していて、演算だとかの定義をずらずら書いていくのがとてもめんどうになったので、Rubyで書いた。名前空間の衝突なんて考えないぜヒャッホウ!

class Vector
  attr_accessor :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def map(*args)
    Vector.new(*args)
  end

  def length
    Math.hypot(@x, @y)
  end
  alias magnitude length
  alias norm      length

  def direction
    cos_theorem(@x, @y, self.length) / @x
  end

  def in_parallel_with?(other)
    self.direction == other.direction
  end

  def -@
    self.map(-@x, -@y)
  end

  def ==(other)
    self.in_parallel_with?(other) && self.length == other.length
  end

  def +(other)
    self.map(@x + other.x, @y + other.y)
  end

  def -(other)
    self + (-other)
  end

  def *(other)
    case other
    when Scalar
      self.__send__(:scalar_multiple, other)
    when Vector
      self.__send__(:dot_product, other)
    else
      raise ArgumentError
    end
  end

  def scalar_multiple(other)
    self.map(@x * other, @y * other)
  end

  def dot_product(other)
    # ...
  end

  private
  def cos_theorem(a, b, c)
    (c ** 2 + a ** 2 - b ** 2) / 2 * a * c
  end
end

module Scalar; end

Numeric.__send__(:extend, Scalar)


教科書と英語版Wikipediaの記事を参照しつつ書いた。英語版Wikipediaの記事はメソッドに名前をつけるために英語表記を気にしただけで、実質的には教科書だけ。

内積 (dot product) と外積 (cross product) はまだ実装していない。あと平面ベクトルになってる。