ゆとりーなの日記

日記的な事を書いて行くと思はれる

ベクトルの内積と外積

C++は戻り値のみが違うだけではオーバーロード出来ません。因って普通の方法ではoperator *単体で内積外積を扱うことはできません。大抵の場合演算子オーバーロードを諦めて関数化するか、時たまoperator %をオーバーロードして片方を担当させるというものを見かけたことがあります。が、頑張ればoperator *単体でもいけますよとの宣伝をここではするわけです。

#include <iostream>

struct vector3 {
  int x;
  int y;
  int z;
};

int dot(const vector3 &lhs, const vector3 &rhs) {
  return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
}

vector3 cross(const vector3 &lhs, const vector3 &rhs) {
  const vector3 temp = {lhs.y * rhs.z - lhs.z * rhs.y, lhs.z * rhs.x - lhs.x * rhs.z, lhs.x * rhs.y - lhs.y * rhs.x};
  return temp;
}

struct vector_mul {
  vector_mul(const vector3 &lhs, const vector3 &rhs) : lhs_(lhs), rhs_(rhs) {}

  operator int() const {
    return dot(lhs_, rhs_);
  }

  operator vector3() const {
    return cross(lhs_, rhs_);
  }

 private:
  const vector3 &lhs_;
  const vector3 &rhs_;
};

vector_mul operator *(const vector3 &lhs, const vector3 &rhs) {
  return vector_mul(lhs, rhs);
}

int main() {
  const vector3 v1 = {0, 1, 2};
  const vector3 v2 = {3, 4, 5};
  const int v1_dot_v2 = v1 * v2;
  const vector3 v1_cross_v2 = v1 * v2;
  std::cout << "内積:" << v1_dot_v2 << std::endl;
  std::cout << "外積:(" << v1_cross_v2.x << "," << v1_cross_v2.y << "," << v1_cross_v2.z << ")" << std::endl;
  return 0;
}
出力
内積:14
外積:(-3,6,-3)

内積外積の公式が怪しいのでもしかすると出力でおかしいことが起こってるかもしれませんが、戻り値だけが違うだけなのにoperator *だけで行けることを示したかっただけなんで悪しからず。間違いに気付いた人は正しく実装してあげてください。
多分参照で耐えると思うのとかコストが重いかもなのとかは知りません。