求圆面积并

#include"iostream"
#include"stack"
#include"cstdio"
#include"string"
#include"cstring"
#include"cctype"
#include"cmath"
#include"vector"
#include"map"
#include"complex"
#include"set"
#include"algorithm"
using namespace std;
const double PI=3.141592654;
double sqr(double x)
{
	return x*x;
}
struct point {
	double x,y;
	point()
	{
	}
	point(double a,double b): x(a),y(b){}
	void input()
	{
		scanf("%lf%lf",&x,&y);
	}
	friend point operator +(const point &a,const point &b)
	{
		return point (a.x+b.x,a.y+b.y);
	}
	friend point operator -(const point &a,const point &b)
	{
		return point (a.x-b.x,a.y-b.y);
	}
	friend bool operator ==(const point &a,const point &b)
	{
		return a.x==b.x&&a.y==b.y;
	}
	friend point operator *(const point &a,const double &b)
	{
		return point (a.x*b,a.y*b);
	}
	friend point operator *(const double &a,const point &b)
	{
		return point (a*b.x,a*b.y);
	}
	friend point operator /(const point &a,const double &b)
	{
		return point (a.x/b,a.y/b);
	}
	double norm()
	{
		return sqrt(sqr(x)+sqr(y));
	}

};
	double det(const point &a,const point&b)
	{
		return a.x*b.y-a.y*b.x;
	}
	double dot(const point &a,const point &b)
	{
		return a.x*b.x+a.y*b.y;
	}
	double dist(const point &a,const point &b)
	{
		return (a-b).norm();
	}
double cross(const point &a,const point &b)
{
	return a.x*b.y-a.y*b.x;
}
point rotate(const point &p,double cost,double sint)
{
	double x=p.x,y=p.y;
	return point (x*cost-y*sint,x*sint+y*cost);
}
pair<point ,point > crosspoint (point ap,double ar,point bp,double br)
{
	double d=(ap-bp).norm();
	double cost=(ar*ar+d*d-br*br)/(2*ar*d);
	double sint=sqrt(1.-cost*cost);
	point v=(bp-ap)/(bp-ap).norm()*ar;
	return make_pair(ap+rotate(v,cost,-sint),ap+rotate(v,cost,sint));
}

struct circle
{
	point p;
	double r;
	bool operator < (const circle &o) const 
	{
		if(r-o.r!=0) return r-o.r==-1;
		if(p.x-o.p.x!=0)
		{
			return p.x-o.p.x==-1;
		}
		return p.y-o.p.y==-1;
	}
	bool operator ==(const circle &o) const 
	{
		return r-o.r==0&&p.x-o.p.x==0&&p.y-o.p.y==0;
	}
};
inline pair<point,point> crosspoint(const circle &a,const circle &b)
{
	return crosspoint(a.p,a.r,b.p,b.r);
}
circle c[1000],tc[1000];
int n,m;
struct node{
	point p;
	double a;
	int d;

	node(const point &p,double a,int d):p(p),a(a),d(d){}
	
	bool operator < (const node &o)const 
	{
		return a<o.a;
	}
};
double arg(point p)
{
	return arg(complex<double>(p.x,p.y));
}
double solve()
{
	sort(tc,tc+m);
	m=unique(tc,tc+m)-tc;
	for(int i=m-1;i>=0;--i)
	{
		bool ok=true;
		for(int j=i+1;j<m;++j)
		{
			double d=(tc[i].p,tc[j].p).norm();
			if(d-abs(tc[i].r-tc[j].r)<=0)
			{
				ok=false;
				break;
			}
		}
		if(ok) c[n++]=tc[i];
	}
	double ans=0;
	for(int i=0;i<n;i++)
	{
		vector<node> event;
		point boundary = c[i].p+point(-c[i].r,0);
		event.push_back(node(boundary,-PI,0));
		event.push_back(node(boundary,PI,0));
		for(int j=0;j<n;j++)
		{
			if(i==j) continue;
			double d=(c[i].p,c[j].p).norm();
			if(d-(c[i].r+c[j].r)<0)
			{
				pair<point,point>ret=crosspoint(c[i],c[j]);
				double x=arg(ret.first-c[i].p);
				double y=arg(ret.second-c[i].p);
				if(x-y>0)
				{
					event.push_back (node(ret.first,x,1));
					event.push_back(node(boundary,PI,-1));
		            event.push_back(node(boundary,-PI,1));
					event.push_back(node(ret.second,y,-1));
				}
				else
				{
					event.push_back (node(ret.first,x,1));
					event.push_back (node(ret.second,y,-1));
				}
			}
		}
		sort(event.begin(),event.end());
		int sum=event[0].d;
		for(int j=1;j<(int) event.size();j++)
		{
			if(sum==0)
			{	   
				ans+=cross(event[j-1].p,event[j].p)/2;
				double x=event[j-1].a;
				double y=event[j].a;
				double area= c[i].r*c[i].r*(y-x)/2;
				point v1 =event[j-1].p-c[i].p;
				point v2 =event[j].p-c[i].p;
				area -= cross(v1,v2)/2;
				ans+=area;
			}
			sum+=event[j].d;
		}
	}
	return ans; 
}
int main()
{
	double l1,l2,ag;
	while(cin>>l1>>l2>>ag)
	{
		point a;
		if(l1/2<1e-10)
			a.x=0;
		else a.x=l1/2;
		a.y=0;
		cout<<a.x<<" "<<a.y<<endl;
		point b;
		if(l2*cos(ag/360.0*2*PI)/2<1e-10)
			b.x=0;
		else b.x=l2*cos(ag/360.0*2*PI)/2;
		if(l2*sin(ag/360.0*2*PI)/2<1e-10)
			b.y=0;
		else
			b.y=l2*sin(ag/360.0*2*PI)/2;
		cout<<b.x<<" "<<b.y<<endl;
		circle aa,bb;
		aa.p=a;
		aa.r=l1/2;
		bb.p=b;
		bb.r=l2/2;
		m=2;
		tc[0]=aa;
		tc[1]=bb;
		double ans=solve();
		//cout<<(PI*0.5*0.5*2)<<endl;
		cout<<(1.5*PI+1)/4<<endl;
		printf("%f\n",ans);
	}
	return 0;
}

/****************************************/
/*	1 1 90								*/
/****************************************/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值