版权声明:虽然本蒟蒻很菜,但各位dalao转载请注明出处谢谢。 https://blog.csdn.net/xuxiayang/article/details/89641889
给定三个点的坐标,求包含这三个点的最小正多边形面积
注意:这里的包含指的是在这个正多边形围城的区域以内(可以在边上)
数据范围:坐标的绝对值不超过1000,小数点后不超过六位
首先这三个点肯定在这个正多边形的顶点上,也可以说正多边形的定点都在这个三角形的外接圆上,详细证明不用我说
如果知道三角形的三点坐标,显然可以利用勾股定理求出三边长:
然后借此利用海伦公式求出面积( 是三角形周长的一半,即 )
然后因为 ,然后结合正弦定理
在任意一个平面三角形中,各边和它所对角的正弦值的比相等且等于外接圆的直径——摘自百度百科
得到 ,即
证明:
上下同乘
,得到
证毕
根据余弦定理
对于任意三角形,任何一边的平方等于其他两边平方的和减去这两边与它们夹角的余弦的积的两倍——摘自百度百科
分别求出三角形三边作为弦所对的圆心角的三角函数值,用反三角函数求出圆心角的度数
由于圆心角的度数都是正多边形中心角度数的倍数,所以可以通过求圆心角度数的最大公约数求出正多边形中心角度数 ,然后知道组成正多边形的每个三角形的面积为 ,而这样的三角形有 个,所以正多边形的面积为
#include<cstdio>
#include<cmath>
using namespace std;
const double Pi=acos(-1.0);
const double EPS=1e-2;
struct Point{double x,y;}p[3];
inline double dis(int i,int j){return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));}
inline double gcd(double a,double b)
{
if(fabs(b)<EPS) return a;if(fabs(a)<EPS) return b;
return gcd(b,fmod(a,b));
}
double len[3],t,S,r,a[3];
signed main()
{
for(register int i=0;i<3;i++) scanf("%lf%lf",&p[i].x,&p[i].y);
for(register int i=0;i<3;i++) len[i]=dis(i,(i+1)%3),t+=len[i];//求出三边长
t/=2;//周长的一半
S=sqrt(t*(t-len[0])*(t-len[1])*(t-len[2]));//海伦公式求面积
r=len[0]*len[1]*len[2]/(4*S);//求外接圆的半径
for(register int i=0;i<2;i++) a[i]=acos(1-len[i]*len[i]/(2*r*r));//反三角函数求圆心角度数
a[2]=2*Pi-a[0]-a[1];
t=gcd(a[0],gcd(a[1],a[2]));//求正多边形的中心角度数
printf("%.6lf",(Pi*r*r*sin(t))/t);//输出
}