#pragma once

#include <vector>

#include <C2/lm/vector2.h>
#include <C2/lm/vector3.h>
#include <C2/lm/range3.h>


namespace lib_geo
{


//! 2Dの形状同士の幾何学演算.
//  交差判定機能、距離計算等.
//  パラメータが3Dベクトルになっている関数は、引数のx,y要素だけを使って
//  各種の計算を行う. zは無視.
//  交差位置を返す場合など, vector3形式で返す場合はz要素は常に0を返す.
class Geom2d
{
public:
	typedef lm::vec2f   vec2f;
	typedef lm::vec3f   vec3f;
	typedef lm::range3f range3f;

public:
	// ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

	// 線分対線分の交差
	static bool Intersect_Segments( const vec3f& a0 , const vec3f& a1 , const vec3f& b0 , const vec3f& b1 );
	static bool Intersect_Segments( const vec3f& a0 , const vec3f& a1 , const vec3f& b0 , const vec3f& b1 , vec3f& intersect_point );
	static bool Intersect_Segments( const vec3f& a0 , const vec3f& a1 , const vec3f& b0 , const vec3f& b1 , float& m , float& n );

	// 線分対直線の交差
	static bool Intersect_Segment_Line( const vec3f& e0 , const vec3f& e1 , const vec3f& line_pos , const vec3f& line_dir );
	static bool Intersect_Segment_Line( const vec3f& e0 , const vec3f& e1 , const vec3f& line_pos , const vec3f& line_dir , vec3f& intersect_point );
	static bool Intersect_Segment_Line( const vec3f& e0 , const vec3f& e1 , const vec3f& line_pos , const vec3f& line_dir , float& m , float& n );

	// 線分対円の交差
	static int Intersect_Circle_Segment( const vec3f& center , const float& radius , const vec3f& e0 , const vec3f& e1 );
	static int Intersect_Circle_Segment( const vec3f& center , const float& radius , const vec3f& e0 , const vec3f& e1 , float& m , float& n );

	// 線分対AABBの交差
	static bool Intersect_AABB_Segment( const range3f& aabb , const vec3f& e0 , const vec3f& e1 );

	// 点が3角形に内包されているか調べる
	static float Intersect_Triangle_Point( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& p );

	// 線分e0-e1上でpに最も近い点を求める.
	static vec3f Closest_Segment_Point( const vec3f& e0 , const vec3f& e1 , const vec3f& p );
	static vec3f Closest_Segment_Point( const vec3f& e0 , const vec3f& e1 , const vec3f& p , float& o_weight );

	// 点列で構成された曲線line上でpに最も近い点を求める.
	static vec3f Closest_CurveLine_Point( const std::vector<vec3f>& line , const vec3f& p );
	static vec3f Closest_CurveLine_Point( const std::vector<vec3f>& line , const vec3f& p , int& o_segment_idx , float& o_norm_pos );

	// 2頂点をxy平面から見たときの距離
	static float DistanceXY( const vec3f& p0 , const vec3f& p1 );
	static float SqDistanceXY( const vec3f& p0 , const vec3f& p1 );

	//! 3角形の面積を求める
	static float AreaSize_Triangle( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 );

	//! 3dベクトルを2dに投影する
	static vec2f Proj_To2d( const vec3f& v );

	//! 重心座標を取得する
	static void Get_BaryCentCoord( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& p , float& u , float& v , float& w );
	static void Get_BaryCentCoord( const vec3f& t0 , const vec3f& t1 , const vec3f& t2 , const vec3f& p , vec3f& bary_coord );

	//! 2つのベクトルの成す角を求める.
	static float Get_Angle( const vec3f& v0 , const vec3f& v1 );
	//! 2つのベクトルの成す角を0〜2PIの範囲で求める.
	static float Get_RoundAngle( const vec3f& v0 , const vec3f& v1 );
};


}
