本文主要是介绍CSU 1503 点到圆弧的距离(最易理解),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
第一步找出圆心
根据题目给出的三点建立两条直线,两直线垂直平分线的交点就是圆心
第二步判断点与圆弧的位置关系
通过分析,可分为两种情况;
情况一,ans1为p到p1的距离减去圆的半径的绝对值
情况二,ans2为p到A,C两点的距离最小值
给出f1,f2,f3,f4分别表示向量 p1A, p1B,p1C,p1P与x正半轴的夹角;
考虑到没有给出给点的顺序,有可能顺时针或逆时针给点。
给出判断的代码:
if(f1<f3){if((f2<=f3&&f2>=f1) == (f4<=f3&&f4>=f1))ans=ans1;else ans=ans2;
}else{if((f2>=f3&&f2<=f1) == (f4>=f3&&f4<=f1))ans=ans1;else ans=ans2;
}
下面分析这段代码:
f1<f3时,表示A,C的位置关系
顺时针给点会形成如下的圆弧;
显然f2 不会满足 f2<=f3&&f2>=f1 如果 f4也不满足 f4<=f3&&f4>=f1,即(f2<=f3&&f2>=f1) == (f4<=f3&&f4>=f1)
则答案是ans1;
如果f4满足 f4<=f3&&f4>=f1 即(f2<=f3&&f2>=f1) != (f4<=f3&&f4>=f1)
则答案是ans2;
逆时针给点会形成如下的圆弧;
显然f2 满足 f2<=f3&&f2>=f1如果 f4也满足 f4<=f3&&f4>=f1,即(f2<=f3&&f2>=f1) == (f4<=f3&&f4>=f1)
则答案是ans1;
如果f4不满足 f4<=f3&&f4>=f1 即(f2<=f3&&f2>=f1) != (f4<=f3&&f4>=f1)
则答案是ans2;
f1>=f3时的情况按照上面的步骤分析一下即可
完整代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct Point{double x,y;Point(double x=0,double y=0):x(x),y(y){}
};
typedef Point Vector;
Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Vector A,double B){return Vector(A.x*B,A.y*B);}
Vector operator / (Vector A,double B){return Vector(A.x/B,A.y/B);}double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;}
double Length(Vector A){return sqrt(Dot(A,A));}
double Cross(Vector A,Vector B){return A.x*B.y-B.x*A.y;}Vector Normal(Vector A){double l=Length(A);return Vector(-(A.y/l),A.x/l);
}
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){Vector u=P-Q;double t=Cross(w,u)/Cross(v,w);return P+v*t;
}
double Distance(Point a,Point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main(){Point a,b,c,p,p1;int Case=0;while(~scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&p.x,&p.y)){Point mid1,mid2;mid1.x=(a.x+b.x)/2;mid1.y=(a.y+b.y)/2;mid2.x=(a.x+c.x)/2;mid2.y=(a.y+c.y)/2;Vector v1=(b-a);Vector v2=(c-a);v1=Normal(v1);v2=Normal(v2);p1=GetLineIntersection(mid1,v1,mid2,v2);//通过三点建立两直线,两直线的垂直平分线交点就是圆心double ans,ans1,ans2;double da,dc,dp1,r;dp1=Distance(p,p1);r=Distance(p1,a);da=Distance(p,a);dc=Distance(p,c);ans1=fabs(dp1-r); ans2=min(da,dc);double f1=atan2(a.y-p1.y,a.x-p1.x);double f2=atan2(b.y-p1.y,b.x-p1.x);double f3=atan2(c.y-p1.y,c.x-p1.x);double f4=atan2(p.y-p1.y,p.x-p1.x);if(f1<f3){if((f2<=f3&&f2>=f1) == (f4<=f3&&f4>=f1))ans=ans1;else ans=ans2;}else{if((f2>=f3&&f2<=f1) == (f4>=f3&&f4<=f1))ans=ans1;else ans=ans2;}printf("Case %d: %.3lf\n",++Case,ans);}return 0;
}
这篇关于CSU 1503 点到圆弧的距离(最易理解)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!