zoukankan      html  css  js  c++  java
  • 圆与多边形的面积交

    圆与多边形的面积交
    https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_H

    int sgn(double x) {
    	if(fabs(x)<eps)return 0;
    	return x<0?-1:1;
    }
    struct Point { //定义点和基本运算
    	double x,y;
    	double ang;
    	Point() {}
    	Point(double x,double y):x(x),y(y) {}
    	Point operator + (Point B) {
    		return Point(x+B.x,y+B.y);
    	}
    	Point operator - (Point B) {
    		return Point(x-B.x,y-B.y);
    	}
    	Point operator * (double k) {
    		return Point(x*k,y*k);   //长度增大k倍
    	}
    	Point operator / (double k) {
    		return Point(x/k,y/k);   //长度缩小k倍
    	}
    	bool operator == (Point B) {
    		return sgn(x-B.x)==0 && sgn(y-B.y)==0;
    	}
    	double operator ^(Point B) {
    		return x*B.y-y*B.x;
    	}
    	double distance(Point p) {
    		return hypot(x-p.x,y-p.y);
    	}
    	double len() {
    		return hypot(x,y);//库函数
    	}
    	Point trunc(double r) {
    		double l = len();
    		if(!sgn(l))return *this;
    		r /= l;
    		return Point(x*r,y*r);
    	}//点积
    	double operator *(const Point &b)const {
    		return x*b.x + y*b.y;
    	}
    	double len2() {
    		return x*x + y*y;
    	}
    	double rad(Point a,Point b) {
    		Point p = *this;
    		return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
    	}
    
    };
    
    typedef Point Vector;
    double Cross(Vector A,Vector B) {
    	return A.x*B.y - A.y*B.x;   //叉积
    }
    
    struct Line {
    	//返回长度的平方
    
    	Point s,e;
    	Line() {}
    	Line(Point _s,Point _e) {
    		s = _s;
    		e = _e;
    	}
    	double length() {
    		return s.distance(e);
    	}
    	double dispointtoline(Point p) {
    		return fabs((p-s)^(e-s))/length();
    	}
    	Point lineprog(Point p) {
    		return s + ( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );
    	}
    };
    
    
    struct Circle {
    	Point p;//圆心
    	double r;//半径
    	Circle() {}
    	Circle(Point p,double r):p(p),r(r) {}
    	Circle(double x,double y,double _r) {
    		p=Point(x,y);
    		r = _r;
    	}
    	int relationcircle(Circle v) {
    		double d = p.distance(v.p);
    		if(sgn(d-r-v.r) > 0)return 5;
    		if(sgn(d-r-v.r) == 0)return 4;
    		double l = fabs(r-v.r);
    		if(sgn(d-r-v.r)<0 && sgn(d-l)>0)return 3;
    		if(sgn(d-l)==0)return 2;
    		if(sgn(d-l)<0)return 1;
    	}
    
    	int relationline(Line v) {
    		double dst = v.dispointtoline(p);
    		if(sgn(dst-r) < 0)return 2;
    		else if(sgn(dst-r) == 0)return 1;
    		return 0;
    	}
    	//点和圆的关系
    //0 圆外
    //1 圆上
    //2 圆内
    	int relation(Point b) {
    		double dst = b.distance(p);
    		if(sgn(dst-r) < 0)return 2;
    		else if(sgn(dst-r)==0)return 1;
    		return 0;
    	}
    
    
    	//求直线和圆的交点,返回交点个数
    	int pointcrossline(Line v,Point &p1,Point &p2) {
    		if(!(*this).relationline(v))return 0;
    		Point a = v.lineprog(p);
    		double d = v.dispointtoline(p);
    		d = sqrt(r*r-d*d);
    		if(sgn(d) == 0) {
    			p1 = a;
    			p2 = a;
    			return 1;
    		}
    		p1 = a + (v.e-v.s).trunc(d);
    		p2 = a - (v.e-v.s).trunc(d);
    		return 2;
    	}
    
    
    	double areatriangle(Point a,Point b) {
    		if(sgn((p-a)^(p-b)) == 0)return 0.0;
    		Point q[5];
    		int len = 0;
    		q[len++] = a;
    		Line l(a,b);
    		Point p1,p2;
    		if(pointcrossline(l,q[1],q[2])==2) {
    			if(sgn((a-q[1])*(b-q[1]))<0)q[len++] = q[1];
    			if(sgn((a-q[2])*(b-q[2]))<0)q[len++] = q[2];
    		}
    		q[len++] = b;
    		if(len == 4 && sgn((q[0]-q[1])*(q[2]-q[1]))>0)swap(q[1],q[2]);
    		double res = 0;
    		for(int i = 0; i < len-1; i++) {
    			if(relation(q[i])==0||relation(q[i+1])==0) {
    				double arg = p.rad(q[i],q[i+1]);
    				res += r*r*arg/2.0;
    			}
    
    
    			else {
    				res += fabs((q[i]-p)^(q[i+1]-p))/2.0;
    			}
    		}
    		return res;
    	}
    };
    
    
    
    struct polypon {
    	int n;
    	Point p[N];
    	Line l[N];
    
    	double areacircle(Circle c) {
    		double ans = 0;
    		for(int i = 0; i < n; i++) {
    			int j = (i+1)%n;
    			if(sgn( (p[j]-c.p)^(p[i]-c.p) ) >= 0)
    				ans += c.areatriangle(p[i],p[j]);
    			else ans -= c.areatriangle(p[i],p[j]);
    		}
    		return fabs(ans);
    	}
    
    };
    
    polypon pp;
    Circle c;
    
    void work() {
    	scanf("%d",&pp.n);
    	scanf("%lf",&c.r);
    	c.p=Point(0,0);
    	for(int i=0; i<pp.n; i++) {
    		scanf("%lf%lf",&pp.p[i].x,&pp.p[i].y);
    	}
    	double ans=pp.areacircle(c);
    	printf("%.6f
    ",ans);
    
    }
    
  • 相关阅读:
    Jmeter之写入测试结果到Excel文件
    jmeter之BeanShell 断言
    jmeter-csv数据文件设置之线程共享模式
    LoadRunner生成随机位数的字符串
    linux命令操作
    LoadRunner函数
    vi常用操作
    LoadRunner常见问题
    面试题库
    jmeter持续集成化(二)---jenkins+ant+jmeter
  • 原文地址:https://www.cnblogs.com/LaiYiC/p/15291323.html
Copyright © 2011-2022 走看看