とりあえずVectorクラス

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

とりあえずVectorクラス

投稿記事 by GRAM » 14年前

うーん、さすがにそろそろオブジェクト全部にxとyを持たせて、座標計算をさせたりするのが面倒になってきた今日この頃。
という事で、ベクトルのクラスを自作してみよう!
…とおもったらSTLにvectorという何とも紛らわしいやつがいたことを思い出した。
先頭を大文字にするという苦肉の策で回避するもなんか納得いかない( ´・ω・)・・・・涙デタ


#include
#define VTOL 0.000001
namespace MyVector{
class Vector{
public:
double x;
double y;
double z;

inline Vector():x(0),y(0),z(0){}
inline Vector(double init_x, double init_y, double init_z = 0)
:x(init_x),y(init_y),z(init_z){
}
inline Vector(const Vector& other){
x=other.x;
y=other.y;
z=other.z;
}
inline Vector& operator=(const Vector& other){
x=other.x;
y=other.y;
z=other.z;
return *this;
}
inline virtual ~Vector(){}

inline bool operator==(const Vector& other){
return abs(other.x-x)VTOL||abs(other.y-y)>VTOL||abs(other.z-z)>VTOL;
}
//以下固有メンバ関数
inline double Length() const{
         //ベクトルの大きさ
return sqrt(x*x+y*y+z*z);
}
inline double Magnitude() const{
return sqrt(x*x+y*y+z*z);
}
inline void Normalize(){
//ベクトルの正規化
double m = sqrt(x*x+y*y+z*z);
if(mMagnitude();
if(abs(mag1)<VTOL || abs(mag2)<VTOL) return -2;
return (x*v.x+y*v.y+z*v.z) / (mag1 *mag2);
}

//スカラーとの乗除
inline Vector& operator*=(const double s){
x*=s;
y*=s;
z*=s;
return *this;
}
inline Vector& operator/=(const double s){
x/=s;
y/=s;
z/=s;
return *this;
}
friend Vector operator*(const double s, const Vector& v);
friend Vector operator*(const Vector& v, const double s);
friend Vector operator/(const Vector& v, const double s);


//ベクトルの三重積
friend double TripleScalar(Vector& u, Vector& v, Vector& w);
//二次元回転(配列は使わず)
friend Vector VRotate2D(const Vector& v, double sin, double cos);
//二つの位置ベクトルから距離を求める
//ユーグリッド距離の二乗(高速)
friend double VDistanceSq(const Vector& v1, const Vector& v2);
//ユーグリッド距離
friend double VEuclideanDistance(const Vector& v1, const Vector& v2);
//マンハッタン距離(経路探索等で使用)
friend double VManhattanDistance(const Vector& v1, const Vector& v2);
//
};

//ベクトルの三重積
inline double TripleScalar(Vector& u, Vector& v, Vector& w){
return double( (u.x * (v.y*w.z-v.z*w.y)) +
(u.y * (v.z*w.x-v.x*w.z)) +
(u.z * (v.x*w.y-v.y*w.x)) );
}

//スカラーとの乗除
inline Vector operator*(const double s, const Vector& v){
return Vector(v.x*s, v.y*s, v.z*s);
}

inline Vector operator*(const Vector& v, const double s){
return Vector(v.x*s, v.y*s, v.z*s);
}

inline Vector operator/(const Vector& v, const double s){
return Vector(v.x/s, v.y/s, v.z/s);
}

inline Vector VRotate2D(const Vector& v, double sin, double cos){
return Vector(v.x*cos-v.y*sin, v.x*sin+v.y*cos);
}

inline double VDistanceSq(const Vector& v1, const Vector& v2){
return (v1-v2)*(v1-v2);
}

inline double VEuclideanDistance(const Vector& v1, const Vector& v2){
return (v1-v2).Length();
}

inline double VManhattanDistance(const Vector& v1, const Vector& v2){
double x = v1.x-v2.x;
double y = v1.y-v2.y;
double z = v1.z-v2.z;
if(x<0)x=-x;
if(y<0)y=-y;
if(z<0)y=-z;
return x+y+z;
}
}


内容はDavid M.BourgさんとGlenn Seemannの
Creating Intelligent Behavior in Gamesを参考にしました。
バグがないことを祈る。
x,y,zは特に変更されても問題ないので、特例的にpublicに。
いやむしろこれくらいだったら、構造体で表現したほうがよかったのかな?
その辺はまだよくわからないです…。
…うーん、多分4次のベクトルは最後の最後で変換するときにしか使わないはずだから、それは作らないことにして、後は行列を処理するクラスがあったほうが便利かな?
最後に編集したユーザー GRAM on 2010年11月06日(土) 21:35 [ 編集 1 回目 ]

アバター
a5ua
記事: 199
登録日時: 14年前

Re: とりあえずVectorクラス

投稿記事 by a5ua » 14年前

STLのvectorは、std名前空間に入っているので、MyVector::vectorとstd::vectorで使い分けできるのでは?

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

Re: とりあえずVectorクラス

投稿記事 by GRAM » 14年前

>>a5uaさん
まったくもってその通りなのですが、名前空間が全部省略できないのは何ともめんどくさいわけで…
まあでもそれくらいしかないのでしょうね^^;

アバター
a5ua
記事: 199
登録日時: 14年前

Re: とりあえずVectorクラス

投稿記事 by a5ua » 14年前

using宣言を使って、using MyVector::Vector;とするのはどうでしょうか。この宣言以降は、Vectorは名前空間を省略できます。

ISLe
記事: 2650
登録日時: 14年前

Re: とりあえずVectorクラス

投稿記事 by ISLe » 14年前

DirectXを使える環境ならD3DXVECTORシリーズをそっくり継承してしまうと楽できるのでは?

アバター
あーる@Reputeless
記事: 84
登録日時: 14年前

Re: とりあえずVectorクラス

投稿記事 by あーる@Reputeless » 14年前

この座標クラスは基底クラスではないので、デストラクタを仮想にする必要はありません。
sizeof(MyVector::Vector) を見てみると、
デストラクタが非仮想の場合は 24 ですが、仮想の場合は、仮想関数テーブルへのポインタを持つので、32 ( アライメント設定によっては 28 ) になります。
また、デストラクタが仮想テーブルポインタ経由で呼ばれるのは、パフォーマンス的に不利です。
private メンバーを持たないので、このクラスは単純な strcut にしても OK だと思います。

アバター
GRAM
記事: 164
登録日時: 14年前
住所: 大阪

Re: とりあえずVectorクラス

投稿記事 by GRAM » 14年前

皆様ありがとうございます
取り敢えず、簡単なものは勉強がてら作るつもりなので、継承は多分行いません(しかし貴重な情報ありがとうございます)
それから仮想関数にするとパフォーマンスが不利になるのですか!たしかに考えてみると、テーブルの参照は邪魔になりそうですね。