POJ 2546刷题思路

1、题目

Description

Your task is to write a program, which, given two circles, calculates the area of their intersection with the accuracy of three digits after decimal point.

Input

In the single line of input file there are space-separated real numbers x1 y1 r1 x2 y2 r2. They represent center coordinates and radii of two circles.

Output

The output file must contain single real number - the area.

Sample Input

20.0 30.0 15.0 40.0 30.0 30.0

Sample Output

608.366

2、解题思路

1、主要考虑两个圆位置关系
2、两个圆的位置是相对的,我动大圆与动小圆都是一个效果
3、默认考虑动小圆更简单
4、圆的位置大概考虑为以下三种情况
5、重合----包含----(小圆一半在大圆里)----相离
下图所示
在这里插入图片描述

3、找临界值

1、临界值主要是两圆的圆心距离与半径之间的关系
2、设r1_r2为两圆心距离,半径大的为maxr,半径小的为minr
3、包含0<=r1_r2<=|r2-r1|
4、一半在大圆里面,利用勾股定理 |r1-r2|<r1_r2<=sqrt((maxr-minr)*(maxr-minr))
5、一半不在大圆到相离: sqrt((maxr-minr)*(maxr-minr))<r1_r2<|r1+r2|
6、相离: r1_r2|>=r1+r2|

4、面积计算

1、包含和相离两种状态不用计算,只需要计算一半在大圆和不在大圆里面
2、一半不在大圆计算,先求出圆心距,在利用海伦公式求出,相应三角形面积,最后根据面积反解出弦长,通过弦长与半径垂直关系,利用反三角函数求出弧对应的弧度,然后利用扇形减去三角形的面积,就为所求面积。
3、一半在大圆里面相对复杂,计算面积与上差不多,只是最后小圆的处理时小圆面积减去扇形面积

5、代码

/*
* 求两个园围成的面积
* 1、两个圆只知道圆心和半径
* 2、意味着只知道圆心距,圆心距求出交点与圆心围成的面积,3边知道
* 3、根据面积反求两圆相交的距离,求出,扇形角度,然后利用扇形减去三角形面积
* 4、分为三种情况 1、两圆完全相互包含(考虑临界)r1_r2+min(r1,r2)<=max(r1,r2)
* 2、两个圆心距比较接近时  max(r1,r2)-min(r1,r2)<=sqrt(r1*r1-r2*r2)
* 3、刚好进入半边圆时 sqrt(r1*r1-r2*r2)<r1_r2<max(r1,r2)
*/
#include<iostream>
#include<math.h>
#define Pi 3.1415926
using namespace std;
int main()
{
	double x1, y1, r1, x2, y2, r2, dist = 0,minr,maxr,s_cir=0,s_tri=0,p=0,h=0;//dist 两个圆心的距离,h为高
	cin >> x1 >> y1 >> r1 >> x2 >> y2 >> r2;
	dist = sqrt(((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)));
	if (r1 > r2)minr = r2, maxr = r1;
	else minr = r1, maxr = r2;
	//1、完全包含情况,小圆面积
	if (dist + minr <= maxr)
	{
		s_cir = Pi * minr * minr;
	}
	//2、小圆半边圆在内部
	if (dist> maxr - minr&& dist <= sqrt(maxr * maxr - minr * minr))
	{
		p = 0.5 * (r1 + r2 + dist);
		s_tri = sqrt(p * (p - r1) * (p - r2) * (p - dist));
		h = 2 * s_tri / dist;
		double angle_r1 = asin(h /minr) * 2;
		double angle_r2 = asin(h /maxr) * 2;
		s_cir = 0.5 * (maxr * (angle_r2 * maxr)) - 2 * s_tri + (Pi * minr * minr - (0.5 * (minr * (angle_r1 * minr))));
	}
	
	//3、圆心不在同一个大圆里面且一半圆在外面
	if (dist >sqrt(maxr * maxr - minr * minr)&&dist<(r1+r2))
	{
		p = 0.5 * (r1 + r2 + dist);
		s_tri = sqrt(p * (p - r1) * (p - r2) * (p - dist));
		h = 2 * s_tri / dist;
		double angle_r1 = asin(h / r1) * 2;
		double angle_r2 = asin(h / r2) * 2;
		s_cir = 0.5 * (r1 * (angle_r1 * r1) + r2 * (angle_r2* r2)) - 2 * s_tri;//扇形面积减去四边形面积

	}
	if (dist >= r1 + r2)
	{
		s_cir = 0;
	}
	printf("%.3f", s_cir);


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值