解题思路:
            

假设半径小的圆为c1,半径大的圆为c2。

c1的半径r1,圆心坐标(x1,y1)。c2的半径r2,圆心坐标(x2,y2)。

d为两圆圆心连线的长度。

相交面积为S

d=sqrt((x1-x2)^2+(y1-y2)^2)

(1)如果r1+r2<=d

那么两圆相离,相交面积S=0

(2)如果r2-r1>=d

那么半径小的圆内含半径大的圆,那么相交面积为小圆的面积S=pi*r1*r1

(3)既非(1)也非(2)

那么两圆相交,连接小圆的圆心与两个圆的交点,连接大圆的圆心和两个圆的交点。

可以发现形成的图形被两个圆心的连线平分成2个全等三角形。

由小圆圆心和交点所连两条线(长度为半径)以及在大圆之内的弧所形成的扇形为S1

由大圆圆心和交点所连两条线(长度为半径)以及在小圆之内的弧所形成的扇形为S2

由小圆圆心和交点所连两条线以及由大圆圆心和交点所连两条线所形成的四边形的面积为S3

可见相交面积S=S1+S2-S3

要求出扇形的面积,要知道扇形的圆心角。

小圆包含的扇形的圆心角为2*a1(考虑一个三角形)

a1=acos((r1^2+d^2-r2^2)/(2.0*r1*d)) 余弦定理

a2=acos((r2^2+d^2-r1^2)/(2.0*r2*d)) 

S1=pi*r1*r1*2*a1/(2*pi)=a1*r1*r1

同理

S2=a2*r2*r2

S3为一个三角形面积的2倍

S3=2*r1*d*sin(a1)/2=r1*d*sin(a1)

则S=a1*r1*r1+a2*r2*r2-r1*d*sin(a1)


注意事项:

参考代码:

#include<stdio.h>
#include<math.h>
#define PI acos(-1.0)  //acos()是反余弦函数,cosπ = -1,所以π = acos(-1)。
int main()
{
	int n;
    float x1,y1,x2,y2,r1,r2;
	float a1,a2,s1,s2;
    double d,s;
	scanf("%d", &n);
	while(n--)
    {
        scanf("%f%f%f%f%f%f",&x1,&y1,&x2,&y2,&r1,&r2);
		d=sqrt(fabs(x1-x2)*fabs(x1-x2)+fabs(y1-y2)*fabs(y1-y2));
		if(d>=r1+r2)
				s=0;
		else if(d<=fabs(r1-r2))
			s=r1<r2? PI * r1 * r1 : PI * r2 * r2;
		else
		{
			a1=2 * acos((r1 * r1 + d * d - r2 * r2) / (2 * r1 * d));
			a2=2 * acos((r2 * r2 + d * d - r1 * r1) / (2 * r2 * d));
			s1=a1 / 2 * r1 * r1 + a2 / 2 * r2 * r2;
			s2=r1 * r1 * sin(a1) / 2 + r2 * r2 * sin(a2) / 2;
			s=s1-s2;
		}
		printf("%.3f\n",s);
    }
	
   
    return 0;
}


点赞(1)
 

0.0分

0 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论