<commit_before>#ifndef __HEADER_WYC_XVECMATH
#define __HEADER_WYC_XVECMATH

/////////////////////////////////////////////////////////////////////////////
//
// ƣXMath Lib
// ߣBlackbird
// 汾1.02
// ṩ3DͼĻѧ֧֡㣬;㡣
//
/////////////////////////////////////////////////////////////////////////////

#include <cassert>
#include "mathex.h"

#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable:4201) //ʹ˷Ǳ׼չ : ƵĽṹ/
#endif // _MSC_VER

#define FAST_MATRIX4_INVERSE // پ

namespace wyc
{

/////////////////////////////////////////////////////////////
//
// 
//

//
// ͨģ
//
template<class T, int D>
class xvector
{
public:
	typedef T element_t;
	enum { DIMENTION = D };
	
	//
	// 
	//
	T	elem[D];

	//
	// 캯
	//
	xvector() 
	{
		assert(D>1);
	}
	xvector(const xvector &v)
	{
		assert(D>1);
		*this=v;
	}
	inline xvector& operator = (const xvector &v)
	{
		memcpy(elem,v.elem,sizeof(T)*D);
		return *this;
	}
	xvector(T val) 
	{
		assert(D>1);
		*this=v;
	}
	xvector& operator = (T val)
	{
		unsigned i=0;
		while(i<D)
			elem[i++]=val;
		return *this;
	}
	template<int D2>
	xvector(const xvector<T,D2> &v) {
		assert(D>1);
		*this=v;
	}
	template<int D2>
	inline xvector& operator = (const xvector<T,D2> &v)
	{
		assert(D!=D2);
		memcpy(elem,v.elem,sizeof(T)*(D<D2?D:D2));
		return *this;
	}

	//
	// ⲿӿ
	//

	// Ԫ
	inline void zero()
	{
		memset(elem,0,sizeof(T)*D);
	}
	// ȫԪشȡ
	inline void set (unsigned i, T val)
	{
		if(i<D) elem[i]=val;
	}
	inline void get (unsigned i, T &val) const
	{
		if(i<D) val=elem[i];
	}
	// Ԫشȡ
	inline T operator () (unsigned i) const
	{
		assert(i<D);
		return elem[i];
	}
	inline T& operator () (unsigned i)
	{
		assert(i<D);
		return elem[i];
	}
	inline T operator [] (unsigned i) const
	{
		assert(i<D);
		return elem[i];
	}
	inline T& operator [] (unsigned i)
	{
		assert(i<D);
		return elem[i];
	}
	// һԪ
	inline xvector& operator += (const xvector &v)
	{
		return add(v);
	}
	inline xvector& operator -= (const xvector &v)
	{
		return sub(v);
	}
	inline xvector& operator *= (T val)
	{
		return scale(val);
	}
	// ȡ
	xvector& reverse()
	{
		for(int i=0; i<D; ++i)
			elem[i]=-elem[i];
		return *this;
	}
	xvector& reverse(const xvector &v)
	{
		for(int i=0; i<D; ++i)
			elem[i]=-v.elem[i];
		return *this;
	}
	// 
	xvector& add (const xvector &v)
	{
		for(int i=0; i<D; ++i)
			elem[i]+=v.elem[i];
		return *this;
	}
	xvector& add (const xvector &v1, const xvector &v2)
	{
		for(int i=0; i<D; ++i)
			elem[i]=v1.elem[i]+v2.elem[i];
		return *this;
	}
	// 
	xvector& sub (const xvector &v)
	{
		for(int i=0; i<D; ++i)
			elem[i]-=v.elem[i];
		return *this;
	}
	xvector& sub (const xvector &v1, const xvector &v2)
	{
		for(int i=0; i<D; ++i)
			elem[i]=v1.elem[i]-v2.elem[i];
		return *this;
	}
	// 
	xvector& scale (T val)
	{
		for(int i=0; i<D; ++i)
			elem[i]*=val;
		return *this;
	}
	xvector& scale (const xvector &v, T val)
	{
		for(int i=0; i<D; ++i)
			elem[i]=v.elem[i]*val;
		return *this;
	}
	// 
	T dot (const xvector &v) const
	{
		T sum=0;
		for(int i=0; i<D; ++i)
			sum+=elem[i]*v.elem[i];
		return sum;
	}
	// ȵƽ
	T length2 () const
	{
		T sum=0;
		for(int i=0; i<D; ++i)
			sum+=elem[i]*elem[i];
		return sum;
	}
	// 
	inline T length () const
	{
		return (sqrt(length2()));
	}
	// һΪλ
	void normalize ()
	{
		T len=length();
		if(fequal(len,T(0)))
			return;
		len=T(1)/len;
		for(int i=0; i<D; ++i)
			elem[i]*=len;
	}
	// Ƚ
	bool operator == (const xvector& v) const 
	{
		for(int i=0; i<D; ++i)
			if(elem[i]!=v.elem[i])
				return false;
		return true;
	}
	bool operator != (const xvector& v) const 
	{
		for(int i=0; i<D; ++i)
			if(elem[i]!=v.elem[i])
				return true;
		return false;
	}
};

/////////////////////////////////////////////////////////////
//
// 2D
//
template<class T>
class xvector<T,2>
{
public:
	typedef T element_t;
	enum { DIMENTION = 2 };

	//
	// 
	//
	union
	{
		T	elem[2];
		struct
		{
			T	x, y;
		};
	};

	//
	// 캯
	//
	xvector() {}

	xvector(T v1, T v2) : x(v1), y(v2) {}

	xvector(const xvector &v)
	{
		*this=v;
	}
	inline xvector& operator = (const xvector &v)
	{
		x=v.x;
		y=v.y;
		return *this;
	}
	xvector(T val) 
	{
		x=y=val;
	}
	inline xvector& operator = (T val)
	{
		x=y=val;
		return *this;
	}
	template<int D2>
	xvector(const xvector<T,D2> &v) {
		*this=v;
	}
	template<int D2>
	inline xvector& operator = (const xvector<T,D2> &v)
	{
		assert(1<D2);
		x=v[0];
		y=v[1];
		return *this;
	}

	//
	// ⲿӿ
	//
	inline void zero()
	{
		x=y=0;
	}
	inline void set(T vx, T vy)
	{
		x=vx;
		y=vy;
	}
	// Ԫشȡ
	inline T operator () (unsigned i) const
	{
		assert(i<2);
		return elem[i];
	}
	inline T& operator () (unsigned i)
	{
		assert(i<2);
		return elem[i];
	}
	inline T operator [] (unsigned i) const
	{
		assert(i<2);
		return elem[i];
	}
	inline T& operator [] (unsigned i)
	{
		assert(i<2);
		return elem[i];
	}
	// 
	inline xvector& operator += (const xvector &v)
	{
		return add(v);
	}
	inline xvector& operator -= (const xvector &v)
	{
		return sub(v);
	}
	inline xvector& operator *= (T val)
	{
		return scale(val);
	}
	inline xvector& reverse()
	{
		x=-x;
		y=-y;
		return *this;
	}
	inline xvector& reverse (const xvector &v)
	{
		x=-v.x;
		y=-v.y;
		return *this;
	}
	inline xvector& add (const xvector &v)
	{
		x+=v.x;
		y+=v.y;
		return *this;
	}
	inline xvector& add (const xvector &v1, const xvector &v2)
	{
		x=v1.x+v2.x;
		y=v1.y+v2.y;
		return *this;
	}
	inline xvector& sub (const xvector &v)
	{
		x-=v.x;
		y-=v.y;
		return *this;
	}
	inline xvector& sub (const xvector &v1, const xvector &v2)
	{
		x=v1.x-v2.x;
		y=v1.y-v2.y;
		return *this;
	}
	inline xvector& scale (T val)
	{
		x*=val;
		y*=val;
		return *this;
	}
	inline xvector& scale (const xvector &v, T val)
	{
		x=v.x*val;
		y=v.y*val;
		return *this;
	}
	inline T dot (const xvector &v) const
	{
		return (x*v.x+y*v.y);
	}
	inline T length2() const
	{
		return (x*x+y*y);
	}
	inline T length() const
	{
		return (sqrt(x*x+y*y));
	}
	void normalize()
	{
		T len=length();
		if(fequal(len,T(0)))
			return;
		len=1/len;
		x*=len;
		y*=len;
	}
	// 2D
	T cross (const xvector &v1) const
	{
		return x*v1.y-y*v1.x;
	}
	// thisʱ뵽vļнǵ
	inline T cos_of_angle(const xvector &v) const
	{
		return (this->dot(v)/(length()*v.length()));
	}
	bool operator == (const xvector& v) const 
	{
		return x==v.x && y==v.y;
	}
	bool operator != (const xvector& v) const 
	{
		return x!=v.x || y!=v.y;
	}
};

//////////////////////////////////////////////////////////////////////////
//
// 3D
//
template<class T>
class xvector<T,3>
{
public:
	typedef T element_t;
	enum { DIMENTION = 3 };

	//
	// 
	//
	union
	{
		T	elem[3];
		struct
		{
			T	x,y,z;
		};
	};

	//
	// 캯
	//

	xvector() {}

	xvector(T v1, T v2, T v3) : x(v1), y(v2), z(v3) {}

	xvector(const xvector &v)
	{
		x=v.x;
		y=v.y;
		z=v.z;
	}
	inline xvector& operator = (const xvector &v)
	{
		x=v.x;
		y=v.y;
		z=v.z;
		return *this;
	}
	xvector(T val) 
	{
		x=y=z=val;
	}
	inline xvector& operator = (T val)
	{
		x=y=z=val;
		return *this;
	}
	template<int D2>
	xvector(const xvector<T,D2> &v) {
		*this=v;
	}
	template<int D2>
	xvector& operator = (const xvector<T,D2> &v)
	{
		assert(3!=D2);
		memcpy(elem,v.elem,sizeof(T)*(3<D2?3:D2));
		return *this;
	}

	//
	// ⲿӿ
	//

	inline void zero()
	{
		x=y=z=0;
	}
	inline void set(T vx, T vy, T vz)
	{
		x=vx;
		y=vy;
		z=vz;
	}
	// Ԫشȡ
	inline T operator () (unsigned i) const
	{
		assert(i<3);
		return elem[i];
	}
	inline T& operator () (unsigned i)
	{
		assert(i<3);
		return elem[i];
	}
	inline T operator [] (unsigned i) const
	{
		assert(i<3);
		return elem[i];
	}
	inline T& operator [] (unsigned i)
	{
		assert(i<3);
		return elem[i];
	}
	// 
	inline xvector& operator += (const xvector &v)
	{
		return add(v);
	}
	inline xvector& operator -= (const xvector &v)
	{
		return sub(v);
	}
	inline xvector& operator *= (T val)
	{
		return scale(val);
	}
	inline xvector& reverse()
	{
		x=-x;
		y=-y;
		z=-z;
		return *this;
	}
	inline xvector& reverse (const xvector &v)
	{
		x=-v.x;
		y=-v.y;
		z=-v.z;
		return *this;
	}
	inline xvector& add (const xvector &v)
	{
		x+=v.x;
		y+=v.y;
		z+=v.z;
		return *this;
	}
	inline xvector& add (const xvector &v1, const xvector &v2)
	{
		x=v1.x+v2.x;
		y=v1.y+v2.y;
		z=v1.z+v2.z;
		return *this;
	}
	inline xvector& sub (const xvector &v)
	{
		x-=v.x;
		y-=v.y;
		z-=v.z;
		return *this;
	}
	inline xvector& sub (const xvector &v1, const xvector &v2)
	{
		x=v1.x-v2.x;
		y=v1.y-v2.y;
		z=v1.z-v2.z;
		return *this;
	}
	inline xvector& scale (T val)
	{
		x*=val;
		y*=val;
		z*=val;
		return *this;
	}
	inline xvector& scale (const xvector &v, T val)
	{
		x=v.x*val;
		y=v.y*val;
		z=v.z*val;
		return *this;
	}
	inline T dot (const xvector &v) const
	{
		return (x*v.x+y*v.y+z*v.z);
	}
	inline T length2() const
	{
		return (x*x+y*y+z*z);
	}
	inline T length() const
	{
		return (sqrt(x*x+y*y+z*z));
	}
	void normalize()
	{
		T len=length();
		if(fequal(len,T(0)))
			return;
		len=1/len;
		x*=len;
		y*=len;
		z*=len;
	}
	// this = v1 cross v2
	xvector& cross (const xvector &v1, const xvector &v2)
	{
		x=v1.y*v2.z-v1.z*v2.y;
		y=v1.z*v2.x-v1.x*v2.z;
		z=v1.x*v2.y-v1.y*v2.x;
		return *this;
	}
	// thisʱ뵽vļнǵ
	inline T cos_of_angle(const xvector &v) const
	{
		return (this->dot(v)/(length()*v.length()));
	}
	bool operator == (const xvector& v) const 
	{
		return x==v.x && y==v.y && z==v.z;
	}
	bool operator != (const xvector& v) const 
	{
		return x!=v.x || y!=v.y || z!=v.z;
	}
};

//////////////////////////////////////////////////////////////////////////
//
// 4D(homogeneous vector)
//
template<class T>
class xvector<T,4>
{
public:
	typedef T element_t;
	enum { DIMENTION = 4 };

	//
	// 
	//
	union
	{
		T	elem[4];
		struct
		{
			T	x,y,z,w;
		};
	};

	//
	// 캯
	//
	xvector() {}

	xvector(T v1, T v2, T v3, T v4=1) : x(v1), y(v2), z(v3), w(v4) {}

	xvector(const xvector &v)
	{
		*this=v;
	}
	inline xvector& operator = (const xvector &v)
	{
		x=v.x;
		y=v.y;
		z=v.z;<commit_msg>Fixed wrong spell<commit_after>#ifndef __HEADER_WYC_XVECMATH
#define __HEADER_WYC_XVECMATH

/////////////////////////////////////////////////////////////////////////////
//
// ƣXMath Lib
// ߣBlackbird
// 汾1.02
// ṩ3DͼĻѧ֧֡㣬;㡣
//
/////////////////////////////////////////////////////////////////////////////

#include <cassert>
#include "mathex.h"

#ifdef _MSC_VER
#pragma warning (push)
#pragma warning (disable:4201) //ʹ˷Ǳ׼չ : ƵĽṹ/
#endif // _MSC_VER

#define FAST_MATRIX4_INVERSE // پ

namespace wyc
{

/////////////////////////////////////////////////////////////
//
// 
//

//
// ͨģ
//
template<class T, int D>
class xvector
{
public:
	typedef T element_t;
	enum { DIMENSION = D };
	
	//
	// 
	//
	T	elem[D];

	//
	// 캯
	//
	xvector() 
	{
		assert(D>1);
	}
	xvector(const xvector &v)
	{
		assert(D>1);
		*this=v;
	}
	inline xvector& operator = (const xvector &v)
	{
		memcpy(elem,v.elem,sizeof(T)*D);
		return *this;
	}
	xvector(T val) 
	{
		assert(D>1);
		*this=v;
	}
	xvector& operator = (T val)
	{
		unsigned i=0;
		while(i<D)
			elem[i++]=val;
		return *this;
	}
	template<int D2>
	xvector(const xvector<T,D2> &v) {
		assert(D>1);
		*this=v;
	}
	template<int D2>
	inline xvector& operator = (const xvector<T,D2> &v)
	{
		assert(D!=D2);
		memcpy(elem,v.elem,sizeof(T)*(D<D2?D:D2));
		return *this;
	}

	//
	// ⲿӿ
	//

	// Ԫ
	inline void zero()
	{
		memset(elem,0,sizeof(T)*D);
	}
	// ȫԪشȡ
	inline void set (unsigned i, T val)
	{
		if(i<D) elem[i]=val;
	}
	inline void get (unsigned i, T &val) const
	{
		if(i<D) val=elem[i];
	}
	// Ԫشȡ
	inline T operator () (unsigned i) const
	{
		assert(i<D);
		return elem[i];
	}
	inline T& operator () (unsigned i)
	{
		assert(i<D);
		return elem[i];
	}
	inline T operator [] (unsigned i) const
	{
		assert(i<D);
		return elem[i];
	}
	inline T& operator [] (unsigned i)
	{
		assert(i<D);
		return elem[i];
	}
	// һԪ
	inline xvector& operator += (const xvector &v)
	{
		return add(v);
	}
	inline xvector& operator -= (const xvector &v)
	{
		return sub(v);
	}
	inline xvector& operator *= (T val)
	{
		return scale(val);
	}
	// ȡ
	xvector& reverse()
	{
		for(int i=0; i<D; ++i)
			elem[i]=-elem[i];
		return *this;
	}
	xvector& reverse(const xvector &v)
	{
		for(int i=0; i<D; ++i)
			elem[i]=-v.elem[i];
		return *this;
	}
	// 
	xvector& add (const xvector &v)
	{
		for(int i=0; i<D; ++i)
			elem[i]+=v.elem[i];
		return *this;
	}
	xvector& add (const xvector &v1, const xvector &v2)
	{
		for(int i=0; i<D; ++i)
			elem[i]=v1.elem[i]+v2.elem[i];
		return *this;
	}
	// 
	xvector& sub (const xvector &v)
	{
		for(int i=0; i<D; ++i)
			elem[i]-=v.elem[i];
		return *this;
	}
	xvector& sub (const xvector &v1, const xvector &v2)
	{
		for(int i=0; i<D; ++i)
			elem[i]=v1.elem[i]-v2.elem[i];
		return *this;
	}
	// 
	xvector& scale (T val)
	{
		for(int i=0; i<D; ++i)
			elem[i]*=val;
		return *this;
	}
	xvector& scale (const xvector &v, T val)
	{
		for(int i=0; i<D; ++i)
			elem[i]=v.elem[i]*val;
		return *this;
	}
	// 
	T dot (const xvector &v) const
	{
		T sum=0;
		for(int i=0; i<D; ++i)
			sum+=elem[i]*v.elem[i];
		return sum;
	}
	// ȵƽ
	T length2 () const
	{
		T sum=0;
		for(int i=0; i<D; ++i)
			sum+=elem[i]*elem[i];
		return sum;
	}
	// 
	inline T length () const
	{
		return (sqrt(length2()));
	}
	// һΪλ
	void normalize ()
	{
		T len=length();
		if(fequal(len,T(0)))
			return;
		len=T(1)/len;
		for(int i=0; i<D; ++i)
			elem[i]*=len;
	}
	// Ƚ
	bool operator == (const xvector& v) const 
	{
		for(int i=0; i<D; ++i)
			if(elem[i]!=v.elem[i])
				return false;
		return true;
	}
	bool operator != (const xvector& v) const 
	{
		for(int i=0; i<D; ++i)
			if(elem[i]!=v.elem[i])
				return true;
		return false;
	}
};

/////////////////////////////////////////////////////////////
//
// 2D
//
template<class T>
class xvector<T,2>
{
public:
	typedef T element_t;
	enum { DIMENSION = 2 };

	//
	// 
	//
	union
	{
		T	elem[2];
		struct
		{
			T	x, y;
		};
	};

	//
	// 캯
	//
	xvector() {}

	xvector(T v1, T v2) : x(v1), y(v2) {}

	xvector(const xvector &v)
	{
		*this=v;
	}
	inline xvector& operator = (const xvector &v)
	{
		x=v.x;
		y=v.y;
		return *this;
	}
	xvector(T val) 
	{
		x=y=val;
	}
	inline xvector& operator = (T val)
	{
		x=y=val;
		return *this;
	}
	template<int D2>
	xvector(const xvector<T,D2> &v) {
		*this=v;
	}
	template<int D2>
	inline xvector& operator = (const xvector<T,D2> &v)
	{
		assert(1<D2);
		x=v[0];
		y=v[1];
		return *this;
	}

	//
	// ⲿӿ
	//
	inline void zero()
	{
		x=y=0;
	}
	inline void set(T vx, T vy)
	{
		x=vx;
		y=vy;
	}
	// Ԫشȡ
	inline T operator () (unsigned i) const
	{
		assert(i<2);
		return elem[i];
	}
	inline T& operator () (unsigned i)
	{
		assert(i<2);
		return elem[i];
	}
	inline T operator [] (unsigned i) const
	{
		assert(i<2);
		return elem[i];
	}
	inline T& operator [] (unsigned i)
	{
		assert(i<2);
		return elem[i];
	}
	// 
	inline xvector& operator += (const xvector &v)
	{
		return add(v);
	}
	inline xvector& operator -= (const xvector &v)
	{
		return sub(v);
	}
	inline xvector& operator *= (T val)
	{
		return scale(val);
	}
	inline xvector& reverse()
	{
		x=-x;
		y=-y;
		return *this;
	}
	inline xvector& reverse (const xvector &v)
	{
		x=-v.x;
		y=-v.y;
		return *this;
	}
	inline xvector& add (const xvector &v)
	{
		x+=v.x;
		y+=v.y;
		return *this;
	}
	inline xvector& add (const xvector &v1, const xvector &v2)
	{
		x=v1.x+v2.x;
		y=v1.y+v2.y;
		return *this;
	}
	inline xvector& sub (const xvector &v)
	{
		x-=v.x;
		y-=v.y;
		return *this;
	}
	inline xvector& sub (const xvector &v1, const xvector &v2)
	{
		x=v1.x-v2.x;
		y=v1.y-v2.y;
		return *this;
	}
	inline xvector& scale (T val)
	{
		x*=val;
		y*=val;
		return *this;
	}
	inline xvector& scale (const xvector &v, T val)
	{
		x=v.x*val;
		y=v.y*val;
		return *this;
	}
	inline T dot (const xvector &v) const
	{
		return (x*v.x+y*v.y);
	}
	inline T length2() const
	{
		return (x*x+y*y);
	}
	inline T length() const
	{
		return (sqrt(x*x+y*y));
	}
	void normalize()
	{
		T len=length();
		if(fequal(len,T(0)))
			return;
		len=1/len;
		x*=len;
		y*=len;
	}
	// 2D
	T cross (const xvector &v1) const
	{
		return x*v1.y-y*v1.x;
	}
	// thisʱ뵽vļнǵ
	inline T cos_of_angle(const xvector &v) const
	{
		return (this->dot(v)/(length()*v.length()));
	}
	bool operator == (const xvector& v) const 
	{
		return x==v.x && y==v.y;
	}
	bool operator != (const xvector& v) const 
	{
		return x!=v.x || y!=v.y;
	}
};

//////////////////////////////////////////////////////////////////////////
//
// 3D
//
template<class T>
class xvector<T,3>
{
public:
	typedef T element_t;
	enum { DIMENSION = 3 };

	//
	// 
	//
	union
	{
		T	elem[3];
		struct
		{
			T	x,y,z;
		};
	};

	//
	// 캯
	//

	xvector() {}

	xvector(T v1, T v2, T v3) : x(v1), y(v2), z(v3) {}

	xvector(const xvector &v)
	{
		x=v.x;
		y=v.y;
		z=v.z;
	}
	inline xvector& operator = (const xvector &v)
	{
		x=v.x;
		y=v.y;
		z=v.z;
		return *this;
	}
	xvector(T val) 
	{
		x=y=z=val;
	}
	inline xvector& operator = (T val)
	{
		x=y=z=val;
		return *this;
	}
	template<int D2>
	xvector(const xvector<T,D2> &v) {
		*this=v;
	}
	template<int D2>
	xvector& operator = (const xvector<T,D2> &v)
	{
		assert(3!=D2);
		memcpy(elem,v.elem,sizeof(T)*(3<D2?3:D2));
		return *this;
	}

	//
	// ⲿӿ
	//

	inline void zero()
	{
		x=y=z=0;
	}
	inline void set(T vx, T vy, T vz)
	{
		x=vx;
		y=vy;
		z=vz;
	}
	// Ԫشȡ
	inline T operator () (unsigned i) const
	{
		assert(i<3);
		return elem[i];
	}
	inline T& operator () (unsigned i)
	{
		assert(i<3);
		return elem[i];
	}
	inline T operator [] (unsigned i) const
	{
		assert(i<3);
		return elem[i];
	}
	inline T& operator [] (unsigned i)
	{
		assert(i<3);
		return elem[i];
	}
	// 
	inline xvector& operator += (const xvector &v)
	{
		return add(v);
	}
	inline xvector& operator -= (const xvector &v)
	{
		return sub(v);
	}
	inline xvector& operator *= (T val)
	{
		return scale(val);
	}
	inline xvector& reverse()
	{
		x=-x;
		y=-y;
		z=-z;
		return *this;
	}
	inline xvector& reverse (const xvector &v)
	{
		x=-v.x;
		y=-v.y;
		z=-v.z;
		return *this;
	}
	inline xvector& add (const xvector &v)
	{
		x+=v.x;
		y+=v.y;
		z+=v.z;
		return *this;
	}
	inline xvector& add (const xvector &v1, const xvector &v2)
	{
		x=v1.x+v2.x;
		y=v1.y+v2.y;
		z=v1.z+v2.z;
		return *this;
	}
	inline xvector& sub (const xvector &v)
	{
		x-=v.x;
		y-=v.y;
		z-=v.z;
		return *this;
	}
	inline xvector& sub (const xvector &v1, const xvector &v2)
	{
		x=v1.x-v2.x;
		y=v1.y-v2.y;
		z=v1.z-v2.z;
		return *this;
	}
	inline xvector& scale (T val)
	{
		x*=val;
		y*=val;
		z*=val;
		return *this;
	}
	inline xvector& scale (const xvector &v, T val)
	{
		x=v.x*val;
		y=v.y*val;
		z=v.z*val;
		return *this;
	}
	inline T dot (const xvector &v) const
	{
		return (x*v.x+y*v.y+z*v.z);
	}
	inline T length2() const
	{
		return (x*x+y*y+z*z);
	}
	inline T length() const
	{
		return (sqrt(x*x+y*y+z*z));
	}
	void normalize()
	{
		T len=length();
		if(fequal(len,T(0)))
			return;
		len=1/len;
		x*=len;
		y*=len;
		z*=len;
	}
	// this = v1 cross v2
	xvector& cross (const xvector &v1, const xvector &v2)
	{
		x=v1.y*v2.z-v1.z*v2.y;
		y=v1.z*v2.x-v1.x*v2.z;
		z=v1.x*v2.y-v1.y*v2.x;
		return *this;
	}
	// thisʱ뵽vļнǵ
	inline T cos_of_angle(const xvector &v) const
	{
		return (this->dot(v)/(length()*v.length()));
	}
	bool operator == (const xvector& v) const 
	{
		return x==v.x && y==v.y && z==v.z;
	}
	bool operator != (const xvector& v) const 
	{
		return x!=v.x || y!=v.y || z!=v.z;
	}
};

//////////////////////////////////////////////////////////////////////////
//
// 4D(homogeneous vector)
//
template<class T>
class xvector<T,4>
{
public:
	typedef T element_t;
	enum { DIMENSION = 4 };

	//
	// 
	//
	union
	{
		T	elem[4];
		struct
		{
			T	x,y,z,w;
		};
	};

	//
	// 캯
	//
	xvector() {}

	xvector(T v1, T v2, T v3, T v4=1) : x(v1), y(v2), z(v3), w(v4) {}

	xvector(const xvector &v)
	{
		*this=v;
	}
	inline xvector& operator = (const xvector &v)
	{
		x=v.x;
		y=v.y;
		z=v.z;
{'fraction_non_alphanumeric': 0.23648103309120258, 'fraction_numerical': 0.016343825665859565, 'mean_word_length': 2.2948313112846934, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1151780', 'n_tokens_mistral': 10397, 'n_tokens_neox': 9701, 'n_words': 2029}