wikioi3273-两圆的交

给定平面上两个圆,第i个圆的圆心为(xi,yi),半径为ri。求两个圆公共部分的面积

给出6个实数 x1,y1,r1,x2,y2,r2     其中 r1,r2>0

输出公共部分面积,结果保留3位小数。

20.0 30.0 15.0 40.0 30.0 30.0

608.366


考虑四种情况,1.相离,2.内含,3.相交中的两个圆心在公共弦两边,4.相交中的两个圆心在公共弦一边。


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>

const double pi=4.0*atan(1.0);

double xa,xb,ya,yb,ra,rb,n;

void init()
{
	freopen("3273.in","r",stdin);
	freopen("3273.out","w",stdout);
}

double qiucos(double a,double b,double c)
{
	return (a*a+b*b-c*c)/(2.0*a*b);
}

double sanjiao(double x,double y,double z)
{
	double p=(x+y+z)/2.0;
	return sqrt(p*(p-x)*(p-y)*(p-z));
}

double max(double a,double b)
{
    	if(a<=b) return b;
    	else return a;
}

double min(double a,double b)
{
    	if(a<=b) return a;
    	else return b;
}


void readdata()
{
	scanf("%lf%lf%lf%lf%lf%lf",&xa,&ya,&ra,&xb,&yb,&rb);
	n=sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
	if( n>=(ra+rb) )
	{
		printf("0.000");
		exit(0);
	}
	if( (max(ra,rb)-n) >= min(ra,rb))
	{
        printf("%.3lf",pi*min(ra,rb)*min(ra,rb));
        exit(0);
    	}
    	if(n<=max(ra,rb))
    	{
 		printf("%.3lf\n", (pi*min(ra,rb)*min(ra,rb)) - ( ((2.0*pi) - acos(qiucos(n,min(ra,rb),max(rb,ra)))*2.0)/(2.0*pi)*(pi*min(ra,rb)*min(ra,rb)) - ( (acos(qiucos(n,max(ra,rb),min(ra,rb)))*2.0)/(2.0*pi)*(pi*max(ra,rb)*max(ra,rb)) - (sanjiao(n,ra,rb)*2))) );
		exit(0);	
    	}
}

void work()
{
	double w=sanjiao(ra,rb,n)*2*2.0/n;
	printf("%.3lf", acos( qiucos(ra,ra,w) )/(2.0*pi)*(pi*ra*ra)+acos( qiucos(rb,rb,w) )/(2.0*pi)*(pi*rb*rb)-sanjiao(ra,rb,n)*2 );
}

int main()
{
	init();
	readdata();
	work();
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值