C++のテンプレートポイントクラス。
ポイントクラスは、画面内の座標(u,v)に使われることが多いが、
今回は必要があり、3次元実数型のデータのポイントクラスを作成。
テンプレートでデータ型を設定できるので、int型のポイントクラスにも
使用できます。
使用するのは下記の「nsPoint.h」だけです。
nsPoint.h
# ifndef NSPOINT_H
# define NSPOINT_H
# include <iostream>
# include <string>
template<typename T> class nsPoint
{
public:
T X,Y,Z;
public:
nsPoint()
{
X = 0;
Y = 0;
Z = 0;
}
nsPoint(T x,T y,T z=0)
{
Set(x,y,z);
}
nsPoint(const nsPoint& h)
{
Set(h.X,h.Y,h.Z);
}
public:
//値セット
void Set(T x,T y,T z=0)
{
X = x;
Y = y;
Z = z;
}
//大きさ
T len()
{
return sqrt(X*X+Y*Y+Z*Z);
}
//正規化(大きさを1にする)
nsPoint<T> norm()
{
T l = len();
nsPoint<T> val(X/l,Y/l,Z/l);
return val;
}
public:
//同値判定
bool operator == (const nsPoint<T>& h)
{
return (h.X == X && h.Y == Y && h.Z == Z);
}
//代入
nsPoint<T>& operator = (const nsPoint<T>& h)
{
Set(h.X,h.Y,h.Z);
return *this;
}
//足し算
nsPoint<T> operator + (const nsPoint<T>& h)
{
nsPoint<T> val(X+h.X,Y+h.Y,Z+h.Z);
return val;
}
//足し算(+=)
nsPoint<T>& operator += (const nsPoint<T>& h)
{
X += h.X;
Y += h.Y;
Z += h.Z;
return *this;
}
//引き算
nsPoint<T> operator - (const nsPoint<T>& h)
{
nsPoint<T> val(X-h.X,Y-h.Y,Z-h.Z);
return val;
}
//引き算(-=)
nsPoint<T>& operator -= (const nsPoint<T>& h)
{
X -= h.X;
Y -= h.Y;
Z -= h.Z;
return *this;
}
//スカラーで掛け算
nsPoint<T> operator * (const T& v)
{
nsPoint<T> val(X*v,Y*v,Z*v);
return val;
}
//スカラーで掛け算(*=)
nsPoint<T> operator *= (const T& v)
{
X *= v;
Y *= v;
Z *= v;
return *this;
}
//スカラーで割り算
nsPoint<T> operator / (const T& v)
{
nsPoint<T> val(X/v,Y/v,Z/v);
return val;
}
//スカラーで掛け算(/=)
nsPoint<T> operator /= (const T& v)
{
X /= v;
Y /= v;
Z /= v;
return *this;
}
//(ポイントをベクトルと見なして)内積
T operator * (const nsPoint<T>& h)
{
T val = X * h.X + Y * h.Y + Z * h.Z;
return val;
}
};
//std::coutへの出力
template<typename T> std::ostream& operator<<(std::ostream& os, nsPoint<T>& dp)
{
os << "(" << std::to_string(dp.X) << "," << std::to_string(dp.Y) << "," << std::to_string(dp.Z) << ")";
return os;
}
# endif
動作確認用のmain()を下記に示します。
main.cpp
int main(int argc, char* argv[])
{
nsPoint<int> ip(1,2,3);
nsPoint<double> dp1(1,2,3);
nsPoint<double> dp2(4,5,6);
nsPoint<double> dp3;
std::cout << "std::coutでの表示" << std::endl;
//整数ポイント表示
std::cout << "ip=" << ip << std::endl;
//実数ポイント表示
std::cout << "dp1=" << dp1 << std::endl;
std::cout << "dp2=" << dp2 << std::endl;
//足し算
dp3 = dp1 + dp2;
std::cout << "足し算 dp3=" << dp3 << std::endl;
//引き算
dp3 = dp1 - dp2;
std::cout << "引き算 dp3=" << dp3 << std::endl;
//スカラーで掛け算
dp3 = dp1 * 2.0;
std::cout << "掛け算 dp3 = dp1 * 2.0 " << dp3 << std::endl;
//スカラーで割り算
dp3 = dp1 / 2.0;
std::cout << "割り算 dp3 = dp1 / 2.0 " << dp3 << std::endl;
//大きさ
double l = dp1.len();
std::cout << "正規化 l = dp1.len() " << dp3 << std::endl;
//正規化
dp3 = dp1.norm();
std::cout << "大きさ dp3 = dp1.norm() " << dp3 << std::endl;
//内積
double inp = dp1 * dp2;
std::cout << "内積 inp = dp1 * dp2 " << std::to_string(inp) << std::endl;
return 0;
}
動作結果を下記に示します。
std::coutでの表示
ip=(1,2,3)
dp1=(1.000000,2.000000,3.000000)
dp2=(4.000000,5.000000,6.000000)
足し算 dp3=(5.000000,7.000000,9.000000)
引き算 dp3=(-3.000000,-3.000000,-3.000000)
掛け算 dp3 = dp1 * 2.0 (2.000000,4.000000,6.000000)
割り算 dp3 = dp1 / 2.0 (0.500000,1.000000,1.500000)
正規化 l = dp1.len() (0.500000,1.000000,1.500000)
大きさ dp3 = dp1.norm() (0.267261,0.534522,0.801784)
内積 inp = dp1 * dp2 32.000000
自分的には結構便利。
X,Yとかは、隠しても面倒なのでpublicにしています。
それでは気が向いたら、何かを作りたいと思います。