/***************************************************************/
//
//
//		DirectX	[ mathematics.cpp ]
//
//											Author	kazuki tanaka
//											Date	2017 6/9
/*---------------------------------------------------------------
■Update : 2017/6/9
			mathematics.cppの作成

/*---------------------------------------------------------------
	Include File
---------------------------------------------------------------*/


#include "mathematics.h"


/*---------------------------------------------------------------
	Macro Difinition
---------------------------------------------------------------*/


/*----------------------------------------------------------------
	static member variable Initialize 
----------------------------------------------------------------*/



// Factorial <階乗>
int Mathematics::Factorial( int index )
{
	int out = 1;
		
	for( int i = index; i > 0; i++ ){
		
		out *= i;
	}
	
	return out;
}
	 
// Power <累乗>
float Mathematics::Power( float value, int index )
{
		
	if( index == 0 ){
		return 1;
	}
		
	float out = value;
		
	if( index > 0 ){
			
		for( int i = 0; i < index; i++ ){
			out *= value;
		}
	}else if( index < 0 ){
		
		for( int i = 0; i > index; i-- ){
			out /= value;
		}
	}
			
	return out;
}
	
// BernsteinBasis <バーンシュタイン基底関数>
float Mathematics::BernsteinBasis( int j, int h, float t )
{
	
	return (Factorial(h)/Factorial(j)*Factorial(h-j))*Power(1-t,h-j)*Power(t,j);
}
	
// BezieCurve <ベジエ曲線>
float Mathematics::BezieCurve( float q0, float q1, float q2, float q3, float t )
{
	
	return (BernsteinBasis(0,3,t)*q0 + BernsteinBasis(1,3,t)*q1 + BernsteinBasis(2,3,t)*q2 + BernsteinBasis(3,3,t)*q3 );
}

// HermiteCurve <エルミート曲線>
float Mathematics::HermiteCurve( float t, float sx, float ex, float sv, float ev )
{
	float h00 = (2 * t * t * t) - (3 * t * t) + 1;
	float h01 = (-2 * t * t * t) + (3 * t * t);
	float h10 = (t * t * t) - (2 * t * t) + t;
	float h11 = (t * t * t) - (t * t);
	return (h00 * sx   + h01 * ex + h10 * sv +	h11 * ev );
}

// degree to radian
float Mathematics::ToRadian( float degree )
{
	return (float)(((degree) * _PI ) / 180);
}

// radian to degree
float Mathematics::ToDegree( float radian )
{
	return (float)(( radian/ _PI ) * 180 );
}

// AffineTransform<アフィン変換>
Vector2& Mathematics::AffineTransform( Vector2& a, Vector2& b, float radian )
{
	return Vector2( ( a.x ) * cosf(radian) - ( b.x ) * sinf(radian), (( a.y ) * sinf(radian) + ( b.y ) * cosf(radian)) );
}

// AffineTransform<アフィン変換> ver Degree
Vector2& Mathematics::AffineTransformDegree( Vector2& a, Vector2& b, float degree )
{
	return Vector2( ( a.x ) * cosf(ToRadian(degree)) - ( b.x ) * sinf(ToRadian(degree)), (( a.y ) * sinf(ToRadian(degree)) + ( b.y ) * cosf(ToRadian(degree))) );
}

// SphericalCoordinateTransform <球面座標変換>
Vector3& Mathematics::SphericalCoordinateTransform( float theta, float phy, float r )
{
	return Vector3( r*sin(theta)*cos(phy), r*sin(theta)*sin(phy), r*cos(theta) );
}









