UVA 10180 Rope Crisis in Ropeland!【判断圆与直线位置】

来源:互联网 发布:mac发送文件给iphone 编辑:程序博客网 时间:2024/05/20 21:23

题目大意:自行百度。

解题策略:


  

首先判断AB所在直线是否与圆相交:
1,不相交:直接计算AB距离即可。

2,相交:
          (1)这里有wa点,还需判断AB线段是否与圆相交,若不想交计算同1;

                     判断方法:若三角形ABO中角A或角B为钝角,线段与圆不相交;

          (2)若AB线段与圆相交,

                     最终答案:ansL = AD + 弧CD + BC,

                     第一步:AD,BC由勾股定理求得;

                     第二步:弧CD = 圆心角COD(弧度制)*半径

                     第三步:利用余弦定理求出角BOA,,角AOD,角B0C ————  角COD = 角BOA - 角AOC-角BOC;

                     由第三步逐步向上操作,既得答案。

3,注意事项:
         (1)计算几何一定要细心再细心,尤其是复杂运算,一定要注意;

         (2)C/C++三角函数针对弧度制操作,注意必要转换;

                     


/*   UVA 10180 Rope Crisis in Ropeland!   AC by J_Dark   ON 2013/5/14 19:52   Time 0.582s*/#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;const double eps = 1e-20;////////////////////////////////////////////////////struct p{    double x, y;    void Set(double a, double b){ x = a; y = b;}    double Ditance(p t){       return sqrt( (t.x-x)*(t.x-x) + (t.y-y)*(t.y-y) );    }}A, B, C, D, O;double rad, AB, AD, AO, BO, BC;////////////////////////////////////////////////////void Input(){    double x1, y1, x2, y2;    cin >> x1 >> y1 >> x2 >> y2 >> rad;    A.Set(x1, y1);    B.Set(x2, y2);    AB = A.Ditance(B);    O.Set(0, 0);}bool isSpecialNI(){    AO = A.Ditance(O);    BO = B.Ditance(O);    if(AO*AO + AB*AB - BO*BO < eps || AB*AB + BO*BO - AO*AO  < eps)       return true;    return false;}double aCos(double a, double b, double c){    return (a*a + b*b - c*c) / (2*a*b);  //这个表达式分母忘记加括号,结果调了一下午T-T}double compute(){    double BOC, AOD, COD, BOA;    BC = sqrt(BO*BO - rad*rad);    AD = sqrt(AO*AO - rad*rad);    BOA = acos(aCos(BO, AO, AB));    BOC = acos(aCos(BO, rad, BC));    AOD = acos(aCos(AO, rad, AD));    COD = (BOA - BOC - AOD);    return COD*rad + BC + AD;}void Solve(){    double AA, BB, CC, dd, ansL;    bool f1;    if(fabs(A.x - B.x) < eps){  //线段斜率不存在        dd = fabs(A.x);    }    else{ //线段斜率存在        AA = (B.y - A.y)/(B.x - A.x);        BB = -1;        CC = A.y - A.x*AA;        dd = fabs(CC/sqrt(AA*AA + BB*BB));    }    if(dd < rad){  //圆与线段所在直线相交        if(isSpecialNI()){   //线段与圆不相交            f1 = false;        }        else{//线段与圆相交 正式进入运算            f1 = true;            ansL = compute();        }    }    else f1 = false;    if(!f1){ //圆与线段不相交        ansL = AB;    }    printf("%.3lf\n", ansL);}////////////////////////////////////////////////////int main(){    int testCase;    while(cin >> testCase)    {        while(testCase--)        {           Input();           Solve();        }    }    return 0;}


原创粉丝点击