前前后后卡了好多次的计算几何,涉及到很多几何题的坑。需要注意的点基本都在下面的注释里。
用到了很多高中要用的几何公式,还牵扯到浮点数的最大公因数问题,总而言之是非常坑爹了。
注意很多非递归的函数可以直接写成 inline 省去很多时间。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define Pi 3.14159265
double x1,y1,x2,y2,x3,y3;
double s1,s2,s3;
double a1,a2,a3;
inline int fequal(double a,double b){
return fabs(a-b)<=0.05;
//题目要求是100边形以下,最小gcd弧度应为2*Pi/100=0.0628,过高精度会引起误差
}
double fgcd(double x,double y){
if(fequal(y,0.0))//这里多了一个分号
return x;
//避免除零
if(fequal(x,0.0))
return y;
return fgcd(y,fmod(x,y));
}
inline int solution(){
s1=sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3));
s2=sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3));
s3=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
double p=(s1+s2+s3)/2.0;
double area=sqrt(p*(p-s1)*(p-s2)*(p-s3));
//海伦公式
double r=s1*s2*s3/(area*4.0);
//正弦定理
a1=acos((2.0*r*r-s1*s1)/(2.0*r*r));
a2=acos((2.0*r*r-s2*s2)/(2.0*r*r));
//余弦定理
//a3=acos((2.0*r*r-s3*s3)/(2.0*r*r));
a3=2.0*Pi-a1-a2;
//提高精度
double gcd=fgcd(a1,a2);
gcd=fgcd(gcd,a3);
//大的弧度角未必是两个小的相加
double n=round(2.0*Pi/gcd);
gcd=2.0*Pi/n;
//提高精度
double ps=0.5*(sin(gcd)*r*r);
double sums=ps*n;
printf("%.8f\n",sums);
return 0;
}
int main(){
cin>>x1>>y1>>x2>>y2>>x3>>y3;
solution();
return 0;
}