1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Posted at

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にしています。
それでは気が向いたら、何かを作りたいと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?