题意:求两点之间的最短距离,如果两点穿过圆,则距离是两条切线加一段弧长,图上有。
分析: 用三角形的余弦定理和正弦定理,可以求出相应的一些角度,其实这道题就是一个简单的几何问题,几何会做这道题就会了。
#include <iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<list>
#include<cstring>
using namespace std;
#define EPS 1e-8
#define N 1005
int ans[N];
struct point
{
double a,b;
point(){}
point(double a,double b):a(a),b(b){}
point operator +(point p)
{
return point(p.a+a,p.b+b);
}
point operator -(point p)
{
return point(a-p.a,b-p.b);
}
point operator *(double p)
{
return point(a*p,b*p);
}
double dot(point p)//内积
{
return (p.a*a+p.b*b);
}
double det(point p)//外积
{
return (a*p.b-b*p.a);
}
};
struct seg
{
int index;
point p1,p2;
};
point p1,p2;
vector<seg>v;
//判断q是否在线段p1-p2上
bool on_str(point p1,point p2,point q)
{
return (abs((p1-q).det(p2-q))<EPS&&(p1-q).dot(p2-q)<EPS);
}
//求两直线交点
point intersection(point p1,point p2,point q1,point q2)
{
return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
}
//两点之间的距离
double dist(point p1,point p2)
{
return sqrt((p1.a-p2.a)*(p1.a-p2.a)+(p1.b-p2.b)*(p1.b-p2.b));
}
//点到直线的距离
double p_seg_dis(point p,point p1,point p2)
{
// A = y1 - y2;
//B = x2 - x1;
//C = x1 * y2 - x2 * y1;
point p3((p1.b-p2.b),(p2.a-p1.a));
// D = fabs(A * x3 + B * y3 + C) / sqrt(A * A + B * B);
// ((p1.b-p2.b)*p.a+(p2.a-p1.a)*p.a)/dis(point())
// cout<<(p.dot(p3)+p1.det(p2))/dist(point(0,0),p3)<<endl;
return fabs((p.dot(p3)+p1.det(p2))/dist(point(0,0),p3));
}
int main()
{
int n;
scanf("%d",&n);
point p1,p2,p(0,0);
while(n--)
{
double r;
scanf("%lf%lf%lf%lf%lf",&p1.a,&p1.b,&p2.a,&p2.b,&r);
if(p_seg_dis(p,p1,p2)>r)
{
printf("%.3f\n",dist(p1,p2));
}
else
{
double ans;
double a=dist(p1,p);
double b=dist(p2,p);
double c=dist(p1,p2);
if((a*a+c*c-b*b)<=0||(b*b+c*c-a*a)<=0)
{
printf("%.3f\n",dist(p1,p2));
continue;
}
ans=sqrt(a*a-r*r)+sqrt(b*b-r*r);
double angle=acos((a*a+b*b-c*c)/(2*a*b))-acos(r/a)-acos(r/b);
ans+=angle*r;
printf("%.3f\n",ans);
}
}
return 0;
}
本文探讨如何利用三角形的余弦定理和正弦定理解决两点间距离问题,涉及几何原理与算法实现,重点突出算法在解决实际问题中的应用。
3069

被折叠的 条评论
为什么被折叠?



