当前位置: 代码迷 >> 综合 >> POJ 2546
  详细解决方案

POJ 2546

热度:25   发布时间:2024-02-24 09:04:31.0

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);}