题目描述
有一个圆形的水池,它的圆心在坐标(0,0)点。水池中有一个桥连接,这个桥可以认为是平面上一条线段AB,并且A点和B点都在水池的边界上。
Roliy想从点F走到点G,F点和G点也都在水池的边界上。他有点胖所以不会游泳,所以他请你帮他写个程序告诉他从F点到G点的最小距离是多少。
输入描述
多组输入数据。
第一行包含一个整数R(1<=R<=100),表示水池的半径。
第二行包含8个实数XA,YA,XB,YB,XF,YF,XG,YG,表示点A,B,F,G的坐标。每个坐标满足|X^2+Y^2-R^2|<10^-8。
输出描述
对于每组测试数据输出答案,保留小数点后两位有效数字。
样例输入
1 0.7296270000 -0.6838453340 0.1980220000 -0.9801975758 0.3149110000 -0.9491212052 -0.7355960000 -0.6774204933 1 0.5173080000 0.8557992949 0.9360380000 -0.3518989380 0.3969010000 -0.9178614254 0.6165430000 -0.7873212363
样例输出
1.15 0.26
根据题目发现有两种方案:
一种是走桥:
一种是不走桥:
(这里说一下,一个圆大的那一段叫优弧,小的叫劣弧,题目要求最短的肯定求劣弧)
圆貌似是初中学的,已经忘完了,于是百度到
两点间的弦长(设为d):d=根号下[(x2-x1)²+(y2-y1)²]
圆心角θ=2arcsin(d/2r)
弧长L=rθ=2r·arcsin(d/2r)
套公式
xc=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));//弦长
yxj1=asin(xc/(2*r))*2,yxj2=PI*2-yxj1;//圆心角
h1=r*yxj1,h2=r*yxj2;//弧长
桥的距离
//AB的距离
AB=sqrt((XA-XB)*(XA-XB)+(YA-YB)*(YA-YB));
全部代码
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<iostream>
#include<algorithm>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<string>
#define ll long long
#define maxn 1000001
#define M(a,b) memset(a,b,sizeof(a))
#define inf 0x7fffffff
#define PI 3.1415926535898
using namespace std;
double min1(double a, double b){
if( a<=b )
return a;
else
return b;
}
double qxc(double x1,double y1,double x2,double y2,double r){
double xc,yxj1,yxj2,h1,h2;
//printf("%0.12lf %0.12lf %0.12lf %0.12lf\n",x1,y1,x2,y2);
xc=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));//弦长
yxj1=asin(xc/(2*r))*2,yxj2=PI*2-yxj1;//圆心角
h1=r*yxj1,h2=r*yxj2;//弧长
//printf("%0.12lf %0.12lf %0.12lf %0.12lf %0.12lf\n",xc,yxj1,yxj2,h1,h2);
return min1(h1,h2);
}
int main() {
double r;
double XA,YA,XB,YB,XF,YF,XG,YG;
double FG,AB,ABFG;
while(cin>>r){
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&XA,&YA,&XB,&YB,&XF,&YF,&XG,&YG);
//FG的弧长
FG=qxc(XF,YF,XG,YG,r);
//AB的距离
AB=sqrt((XA-XB)*(XA-XB)+(YA-YB)*(YA-YB));
//ABFG的距离
ABFG=min1(qxc(XA,YA,XF,YF,r),qxc(XB,YB,XF,YF,r))+min1(qxc(XB,YB,XG,YG,r),qxc(XA,YA,XG,YG,r));
printf("%.2lf\n",min1(FG,AB+ABFG));
}
return 0;
}