题意:给你四个点,找出一个点到四个点的距离最小
四边形的费马点:凸边形是两对角线的交点,凹边形式凹点。
PS:
三角形的费马点:
1.若三角形3个内角均小于120°,那么3条距离连线正好三等分费马点所在的周角,即该点所对三角形三边的张角相等,均为120°。所以三角形的费马点也称为三角形的等角中心。
2.若三角形有一内角大于等于120°,则此钝角的顶点就是距离和最小的点。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<string>
#include<queue>
#include<map>
#include<math.h>
#include<algorithm>
#include<iostream>
using namespace std;
const int kind = 26;
const int maxn = 250*1000; //注意RE,单词长度*单词个数
const int M = 5100000;
struct Point
{
double x,y;
};
//小于0,说明向量p0p1的极角大于p0p2的极角
double multiply(Point p1,Point p2,Point p0)
{
return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
double dis(Point p1,Point p2)
{
return(sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)));
}
void Graham_scan(Point PointSet[],Point ch[],int n,int &len)
{
int i,j,k=0,top=2;
Point tmp;
//找到最下且偏左的那个点
for(i=1;i<n;i++)
if ((PointSet[i].y<PointSet[k].y)||((PointSet[i].y==PointSet[k].y)&&(PointSet[i].x<PointSet[k].x)))
k=i;
//将这个点指定为PointSet[0]
tmp=PointSet[0];
PointSet[0]=PointSet[k];
PointSet[k]=tmp;
//按极角从小到大,距离偏短进行排序
for (i=1;i<n-1;i++)
{
k=i;
for (j=i+1;j<n;j++)
if( (multiply(PointSet[j],PointSet[k],PointSet[0])>0)
||((multiply(PointSet[j],PointSet[k],PointSet[0])==0)
&&(dis(PointSet[0],PointSet[j])<dis(PointSet[0],PointSet[k]))) )
k=j;//k保存极角最小的那个点,或者相同距离原点最近
tmp=PointSet[i];
PointSet[i]=PointSet[k];
PointSet[k]=tmp;
}
//第三个点先入栈
ch[0]=PointSet[0];
ch[1]=PointSet[1];
ch[2]=PointSet[2];
//判断与其余所有点的关系
for (i=3;i<n;i++)
{
//不满足向左转的关系,栈顶元素出栈
while(multiply(PointSet[i],ch[top],ch[top-1])>=0) top--;
//当前点与栈内所有点满足向左关系,因此入栈.
ch[++top]=PointSet[i];
}
len=top+1;
}
Point intersection(Point u1,Point u2,Point v1,Point v2)
{
Point ret=u1;
double t=((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
/((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
ret.x+=(u2.x-u1.x)*t;
ret.y+=(u2.y-u1.y)*t;
return ret;
}
Point p[4],ch[4],point;
int len;
int main()
{
int x1, y1, x2, y2, x3, y3, x4, y4;
int x[4],y[4];
while(scanf("%lf%lf",&p[0].x,&p[0].y))
{
int flag=0;
if(p[0].x!=-1||p[0].y!=-1) flag=1;
for(int i=1;i<4;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
if(p[i].x!=-1||p[i].y!=-1)
flag=1;
}
if(!flag) break;
double minn=10000000,ans=0.0;
int k=0;
Graham_scan(p,ch,4,len);
for(int i=0;i<4;i++)
{
ans=0.0;
for(int j=0;j<4;j++)
{
ans+=dis(p[i],p[j]);
}
if(ans<minn)
minn=ans;
}
point=intersection(p[0],p[2],p[1],p[3]);
//printf("%lf %lf\n",point.x,point.y);
ans=0.0;
for(int i=0;i<4;i++)
{
ans+=dis(p[i],point);
}
printf("%.4lf\n",min(minn,ans));
}
return 0;
}
/*
0 0 0 0 1 0 0 1
0 0 1 1 1 0 0 1
1 1 1 1 1 1 1 1
-1 -1 -1 -1 -1 -1 -1 -1
*/