//Computational Geometry 1 points //by kevin_samuel(fenice) Soochow University 2011 //[email protected] //kevin-samuel.myazure.org //temple #include <iostream> #include <cmath> #include <algorithm> #include <cstdio> using namespace std; //define const double EPS = 1e-8; const double PI = acos(-1.0); //point class Point { public: double x; double y; Point(){}; Point(double x,double y):x(x),y(y){}; //operator //operator= Point& operator=(const Point& _P) { x = _P.x; y = _P.y; return *this; } //operator* double operator*(const Point& _P)const { return x*_P.y - y *_P.x; } //operator- Point operator-(const Point& _P)const { return Point(x - _P.x,y - _P.y); } //operator== bool operator==(const Point& _P)const { if(fabs(_P.x - x) < EPS && fabs(_P.y - y) < EPS) return true; else return false; } bool operator!=(const Point& _P)const { return ((*this) == _P) == false; } //dot product static double dotProduct(Point s1,Point e1,Point s2,Point e2) { double result = 0; double x1 = e1.x - s1.x; double y1 = e1.y - s1.y; double x2 = e2.x - s2.x; double y2 = e2.y - s2.y; result = x1*x2 + y1*y2; return result; } //cross product 1 (4 point-type params) static double crossProduct(Point s1,Point e1,Point s2,Point e2) { double result = 0; double x1 = e1.x - s1.x; double y1 = e1.y - s1.y; double x2 = e2.x - s2.x; double y2 = e2.y - s2.y; result = x1*y2 - x2*y1; return result; } //cross product 2 (3 point-type params) static double crossProduct(Point p1,Point p2,Point p0) { return crossProduct(p0,p1,p0,p2); } //Is on segment or line static bool onSegment(Point Pi,Point Pj,Point Q) { if(Q.x >= min(Pi.x,Pj.x) && Q.x <= max(Pi.x,Pj.x) && Q.y >= min(Pi.y,Pj.y) && Q.y <= max(Pi.y,Pj.y) && crossProduct(Q,Pj,Pi) == 0 ) return true; else return false; } //Is on segment bool IsOnSegment(Point Pi,Point Pj) { if(this->x >= min(Pi.x,Pj.x) && this->x <= max(Pi.x,Pj.x) && this->y >= min(Pi.y,Pj.y) && this->y <= max(Pi.y,Pj.y) && Point::crossProduct(*this,Pj,Pi) == 0 ) return true; else return false; } //Is inside triangle bool inTriangle(Point A,Point B,Point C) { double Sabc = fabs(Point::crossProduct(B,C,A)); double Spab = fabs(Point::crossProduct(A,B,(*this))); double Spac = fabs(Point::crossProduct(A,C,(*this))); double Spbc = fabs(Point::crossProduct(B,C,(*this))); if(Spbc + Spab + Spac == Sabc) return true; else return false; } //Is inside polygon //polys[] ,0-n bool insidePolygon(Point *polys,int n) { int counter = 0; double xinters; Point p1,p2; p1 = polys[0]; for(int i = 1; i < n; i++) { p2 = polys[i % n]; if(Point::onSegment(p1,p2,(*this)) == true) return true; if((*this).y > min(p1.y,p2.y) && (*this).y <= max(p1.y,p2.y)) { if((*this).x <= max(p1.x,p2.x) && p1.y != p2.y) { xinters = ((*this).y - p1.y)*(p2.x - p1.x)/(p2.y - p1.y) + p1.x; if(p1.x == p2.x || (*this).x <= xinters) counter++; } } p1 = p2; } if(counter % 2 == 0) return false; return true; } //distance^2 double dis2(const Point& _P)const { return (x - _P.x)*(x - _P.x) + (y - _P.y)*(y - _P.y); } //distance double dis(const Point& _P)const { return sqrt(dis2(_P)); } }; //test zone int main() { // return 0; }