C++のテンプレートポイントクラス

C++のテンプレートポイントクラス。
ポイントクラスは、画面内の座標(u,v)に使われることが多いが、
今回は必要があり、３次元実数型のデータのポイントクラスを作成。
テンプレートでデータ型を設定できるので、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にしています。
それでは気が向いたら、何かを作りたいと思います。