- 借这道题夯实一下计算几何的基础
- 向量积:顺负逆正
- 两线交点和夹角都是借助向量工具求解的
- 分类讨论:圆弧小于180度时,减去三角形面积;大于180度时,加上三角形面积
- 割补法求面积(正难则反)
- C++中的角度以弧度制表示
点击查看代码
#include <bits/stdc++.h>
#define pdd pair<double,double>
using namespace std;
const double pi=acos(-1.0);
int s[10],t[10],r;
pdd operator -(pdd a,pdd b)
{
pdd c;
c.first=a.first-b.first;
c.second=a.second-b.second;
return c;
}
pdd operator +(pdd a,pdd b)
{
pdd c;
c.first=a.first+b.first;
c.second=a.second+b.second;
return c;
}
pdd operator *(double a,pdd b)
{
pdd c;
c.first=b.first*a;
c.second=b.second*a;
return c;
}
pdd get_dot(int rad)
{
return make_pair(cos(rad*pi/180.0)*r,sin(rad*pi/180.0)*r);
}
double len(pdd a)
{
return sqrt(a.first*a.first+a.second*a.second);
}
double mul1(pdd a,pdd b)
{
return a.first*b.first+a.second*b.second;
}
double mul2(pdd a,pdd b)
{
return a.first*b.second-a.second*b.first;
}
pdd jiaodian(pdd a,pdd b,pdd c,pdd d)
{
pdd l1=b-a,l2=d-c;
return c+mul2(c-a,l1)/mul2(l1,l2)*l2;
}
double stri(pdd a,pdd b,pdd c)
{
pdd l1=b-a,l2=c-a;
return fabs(0.5*mul2(l1,l2));
}
int sgn(double x)
{
if(x>0)
{
return 1;
}
return -1;
}
double shu(pdd a,pdd b)
{
double w1=mul2(a,b);
double w2=(acos(mul1(a,b)/len(a)/len(b)));
if(w1<0)
{
w2=2*pi-w2;
}
return (w2/(2*pi))*pi*r*r-stri(a,b,make_pair(0,0))*sgn(w1);
}
void lunhuan()
{
for(int i=1;i<=5;i++)
{
s[i-1]=s[i];
t[i-1]=t[i];
}
s[5]=s[0];
t[5]=t[0];
}
int main()
{
int T;
cin>>T;
while(T--)
{
r=read1();
for(int i=1;i<=5;i++)
{
s[i]=read1();
}
for(int i=1;i<=5;i++)
{
t[i]=read1();
}
double ans=pi*r*r;
for(int i=1;i<=5;i++)
{
pdd tmp=jiaodian(get_dot(s[1]),get_dot(t[4]),get_dot(s[2]),get_dot(t[5]));
ans-=stri(get_dot(s[1]),get_dot(t[5]),tmp);
ans-=shu(get_dot(t[5]),get_dot(s[1]));
lunhuan();
}
printf("%.9f\n",ans);
}
return 0;
}