POJ 2546 Circular Area(计算几何 两圆相交面积)

16 篇文章 0 订阅

题目描述:

Circular Area

Time Limit: 1000MS Memory Limit: 65536K

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

计算几何初接触,本来想先做个水题找找手感结果被无限卡制,最后没办法只好查题解,原来是g++在卡精度……用c++交就很顺利的A过了。

整理了一下自己写的比较顺手的方式。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define MAX 100010
#define MM 105
#define INF 0x3f3f3f3f
#define PI acos(-1.0)

using namespace std;

struct point
{
    double x, y;

    double len(point t)
    {
        return sqrt((x - t.x) * (x - t.x) + (y - t.y) * (y - t.y));
    }
};

struct circle
{
    point p;
    double r;

    double dis(circle c)
    {
        return p.len(c.p);
    }
};

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

double Straingle(double a, double b, double angle)
{
    return a * b * sin(angle);
}

double Scircle(double r, double angle)
{
    return angle * r * r;
}

double getans(circle a, circle b)
{
    double d = a.dis(b);
    if(d >= a.r + b.r)
    {
        return 0;
    }
    else if(d <= fabs(a.r - b.r))
    {
        double r = a.r < b.r ? a.r : b.r;
        return PI * r * r;
    }
    else
    {
        double ang1 = acos(cosine(a.r, d, b.r));
        double ang2 = acos(cosine(b.r, d, a.r));
        double ans = Scircle(a.r, ang1) + Scircle(b.r, ang2) - Straingle(a.r, d, ang1);
        return ans;
    }
}

int main()
{
    circle c1, c2;
    while(~scanf("%lf %lf %lf %lf %lf %lf", &c1.p.x, &c1.p.y, &c1.r, &c2.p.x, &c2.p.y, &c2.r))
    {
        printf("%.3lf\n", getans(c1, c2));
    }
    return 0;
}

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值