無關青雲路,無關詩書,無你處,無江湖
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
每個圓的屬性可以使用三個參數來描述,x-圓心橫座標,y-圓心縱座標,r-半徑,現給出兩個圓分別的參數,求兩個圓相交的面積。
Input
第一行是一個正整數T(T≤12),表示有T組測試數據 接下來有T行,每行有六個正整數描述兩個圓的屬性x1,y1,r1,x2,y2,r2。 0≤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;
}