/*
	AramakiOnline
	Copyright (C) 2008 superbacker

	This program is free software; you can redistribute it and/or modify it under the terms
	of the GNU General Public License as published by the Free Software Foundation;
	either version 3 of the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY
	WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
	FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along with this
	program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef POINT2D_H_
#define POINT2D_H_

struct Point2d {
	double x,y;

	inline Point2d() : x(0),y(0) {}

	inline Point2d(double x,double y) : x(x),y(y) {}

	//スカラーを求める
	inline double scalar() const {
		return sqrt(x*x+y*y);
	}

	//正規化
	inline void normalize() {
		double scalar;

		//スカラーを求める
		scalar=this->scalar();

		//大きさがない
		if (scalar==0.0) return;

		//各成分をスカラーで割る
		x/=scalar;
		y/=scalar;
	}

	//加法
	inline Point2d operator+(const Point2d &point) const {
		Point2d newPoint;

		newPoint.x=x+point.x;
		newPoint.y=y+point.y;

		return newPoint;
	}

	inline Point2d &operator+=(const Point2d &point) {
		x+=point.x;
		y+=point.y;

		return *this;
	}

	//減法
	inline Point2d operator-(const Point2d &point) const {
		Point2d newPoint;

		newPoint.x=x-point.x;
		newPoint.y=y-point.y;

		return newPoint;
	}

	inline Point2d &operator-=(const Point2d &point) {
		x-=point.x;
		y-=point.y;

		return *this;
	}

	//実数倍
	inline Point2d operator*(double scale) const {
		Point2d newPoint;

		newPoint.x=x*scale;
		newPoint.y=y*scale;

		return newPoint;
	}

	inline Point2d &operator*=(double scale) {
		x*=scale;
		y*=scale;

		return *this;
	}

	//内積を求める
	inline double dot(const Point2d &point) const {
		return x*point.x+y*point.y;
	}

	//外積を求める
	inline double cross(const Point2d &point) const {
		return x*point.y-y*point.x;
	}

	//法線ベクトルを生成
	inline void normalVector(const Point2d &lineStart,const Point2d &lineEnd) {
		Point2d point=lineEnd-lineStart;
		x=-point.y;
		y=point.x;
		normalize();
	}
};

inline bool collideLine(const Point2d &line1Start,const Point2d &line1End,const Point2d &line2Start,const Point2d &line2End) {
	if (((line1Start.x-line1End.x)*(line2Start.y-line1Start.y)+(line1Start.y-line1End.y)*(line1Start.x-line2Start.x))*((line1Start.x-line1End.x)*(line2End.y-line1Start.y)+(line1Start.y-line1End.y)*(line1Start.x-line2End.x))<0) {
		if (((line2Start.x-line2End.x)*(line1Start.y-line2Start.y)+(line2Start.y-line2End.y)*(line2Start.x-line1Start.x))*((line2Start.x-line2End.x)*(line1End.y-line2Start.y)+(line2Start.y-line2End.y)*(line2Start.x-line1End.x))<0) {
			return true;
	    }
	}

	return false;
}

#endif /* POINT2D_H_ */
