UESTC1713(求兩個圓的面積的交)

無關青雲路,無關詩書,無你處,無江湖

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)
 

每個圓的屬性可以使用三個參數來描述,xx-圓心橫座標,yy-圓心縱座標,rr-半徑,現給出兩個圓分別的參數,求兩個圓相交的面積。

Input

第一行是一個正整數TT(T12T≤12),表示有TT組測試數據 接下來有T行,每行有六個正整數描述兩個圓的屬性x1,y1,r1,x2,y2,r2x1,y1,r1,x2,y2,r2。 0x1,y1,r1,x2,y2,r25000≤x1,y1,r1,x2,y2,r2≤500

Output

對於每組測試數據輸出一行,表示兩個圓相交的面積大小,結果保留6位小數

Sample input and output

Sample Input Sample Output
3
0 0 10 15 0 10
-10 -10 5 0 -10 10
100 100 20 100 110 20
45.331175
35.076661
860.843690

Hint

By Qyitong

Source

2017 UESTC Training for Math


解題思路:直接求面積的交就行

#include<stdio.h>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const double eps = 1e-10;
const double pi = acos(-1.0);
struct Point{
    double x, y;
    Point(double _x = 0, double _y = 0){
        x = _x;
        y = _y;
    }
};
typedef Point Vector;
Vector operator +(Vector A, Vector B) {return Vector(A.x + B.x, A.y + B.y);}//向量加
Vector operator -(Vector A, Vector B) {return Vector(A.x - B.x, A.y - B.y);}//向量減
Vector operator *(Vector A, double p) {return Vector(p * A.x, p * A.y);}//向量的數乘
Vector operator /(Vector A, double p) {return Vector(A.x / p, A.y / p);}//向量的數除
Vector operator -(Vector A) {return Vector(-A.x, -A.y);}//向量的取反
int dcmp(double x)
{
    if(fabs(x) < eps) return 0;
    else return x < 0 ? -1 : 1;
}
bool operator == (const Point& a, const Point& b) {
    return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
double Cross(Vector A, Vector B)//求解向量叉積
{
    return A.x * B.y - A.y * B.x;
}
double Dot(Vector A, Vector B)//求解向量數量積
{
    return A.x * B.x + A.y * B.y;
}
double xmulti(Point p, Point a, Point b)//求向量pa叉乘pb
{
    return (a.x - p.x) * (b.y - p.y) - (a.y - p.y) * (b.x - p.x);
}
double getDis(Point p1, Point p2)
{
    return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
struct circle{
    Point p0;
    double r;
    circle(Point _p0 = Point(0, 0), double _r = 0){
        p0 = _p0;
        r = _r;
    }
};
int circle_loc(circle cc1, circle cc2)//判斷兩圓的位置關係,-1爲包含(內切),0爲相交,1爲相離(外切)
{
    double d = getDis(cc1.p0, cc2.p0);
    double r1 = cc1.r;
    double r2 = cc2.r;
    double x1 = d - (r1 + r2);
    if(dcmp(x1) >= 0) return 1;
    double x2 = fabs(r1 - r2);
    double x3 = d - x2;
    if(dcmp(x3) <= 0) return -1;
    else return 0;
}
double area_circle(circle cc1, circle cc2)
{
    double d = getDis(cc1.p0, cc2.p0);
    double r1 = cc1.r;
    double r2 = cc2.r;
    int rala = circle_loc(cc1, cc2);
    if(rala == 1) return 0;
    if(rala == -1)
    {
        return (pi * min(r1, r2) * min(r1, r2));
    }
    double angle1 = acos((r1 * r1 + d * d - r2 * r2) / (2 * r1 * d));
    double angle2 = acos((r2 * r2 + d * d - r1 * r1) / (2 * r2 * d));
    double s = d * r1 * sin(angle1);
    double s1 = angle1 * r1 * r1;
    double s2 = angle2 * r2 * r2;
    return (s1 + s2 - s);
}
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        circle c1, c2;
        scanf("%lf%lf%lf%lf%lf%lf", &c1.p0.x, &c1.p0.y, &c1.r, &c2.p0.x, &c2.p0.y, &c2.r);
        printf("%.6lf\n", area_circle(c1, c2));
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章