#include<iostream> #include<cstdio> #include<cmath> using namespace std; #define EPS 1e-8 struct Point{ double x,y; Point(){} Point(double xx, double yy):x(xx), y(yy){} }; struct Line{ Point a,b; }; /* 向量p0p1与p0p2的叉积 =0说明三点共线 >0则p0p2在p0p1的逆时针方向 <0则p0p2在p0p1的顺时针方向 */ double xmult(Point p1, Point p2, Point p0) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } //两点距离 double dis(Point p1, Point p2) { double x = p1.x-p2.x; double y = p1.y-p2.y; return sqrt(x*x+y*y); } //p点到直线ab的距离 double disptoline(Point p, Point a, Point b) { //fabs(xmult(p,a,b))是以pa,pb为邻边的平行四边形面积 return fabs(xmult(p,a,b))/dis(a,b); } //两条直线的交点,注意判断直线是否平行或重合 Point intersection(Point A, Point B, Point C, Point D) { //a1*x+b1*y=c1;a2*x+b2*y=c2; //得到直线的3个系数 double a1 = A.y-B.y; double b1 = B.x-A.x; double c1 = A.x*B.y-B.x*A.y; double a2 = C.y-D.y; double b2 = D.x-C.x; double c2 = C.x*D.y-D.x*C.y; double x = (b1*c2-b2*c1)/(a1*b2-a2*b1); double y = (a2*c1-a1*c2)/(a1*b2-a2*b1); return Point(x,y); } //点到直线上的最近点 Point ptoline(Point p,Line l) { Point t=p; t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x; return intersection(p,t,l.a,l.b); } //点是否在线段l上 bool pisonline(Line l,Point p) { return( (xmult(l.a,l.b,p)==0) &&( ( (p.x-l.a.x)*(p.x-l.b.x)<=0 )&&( (p.y-l.a.y)*(p.y-l.b.y)<=0 ) ) ); } //点到线段上的最近点 Point ptoseg(Point p,Line l) { Point t=p; t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x; if(xmult(l.a,t,p)*xmult(l.b,t,p)>EPS) return dis(p,l.a)<dis(p,l.b)?l.a:l.b; return intersection(p,t,l.a,l.b); } //点到线段距离 double disptoseg(Point p,Line l) { Point t=p; t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x; if(xmult(l.a,t,p)*xmult(l.b,t,p)>EPS) return dis(p,l.a)<dis(p,l.b)?dis(p,l.a):dis(p,l.b); return fabs(xmult(p,l.a,l.b))/dis(l.a,l.b); } //判断直线是否重合 bool isSame(Point A,Point B,Point C,Point D) { if(fabs(xmult(A,B,C))<=EPS&&fabs(xmult(A,B,D))<=EPS) return true; return false; } //判断直线是否平行,判断平行之前先判断是否重合 bool isParallel(Point A,Point B,Point C,Point D) { if((A.y-B.y)*(D.x-C.x)==(B.x-A.x)*(C.y-D.y)) return true; return false; } //根据圆周上的三点,求出圆心 Point getCir(Point a,Point b,Point c) { Line u,v; u.a.x = (a.x+b.x)/2; u.a.y = (a.y+b.y)/2; u.b.x = u.a.x-a.y+b.y; u.b.y = u.a.y+a.x-b.x; v.a.x = (a.x+c.x)/2; v.a.y = (a.y+c.y)/2; v.b.x = v.a.x-a.y+c.y; v.b.y = v.a.y+a.x-c.x; return intersection(u.a, u.b, v.a, v.b); } //判断线段ab与线段cd是否相交 bool SegIntersection(Point a, Point b, Point c, Point d) //判断线段相交 { if (min(a.x, b.x) <= max(c.x, d.x) && min(a.y, b.y) <= max(c.y, d.y) && min(c.x, d.x) <= max(a.x, b.x) && min(c.y, d.y) <= max(a.y, b.y) && xmult(a, b, c) * xmult(a, b, d) <= EPS && xmult(c, d, a) * xmult(c, d, b) <= EPS) return true; return false; }