圆与线段的交点

poj 3819 

给出一条线段的两个端点,再给出n个圆,求出这条线段被所有圆覆盖的部分占了整条线段的百分比。


圆与线段的交点 :

向量AB 的参数方程  P = A + t * (B - A)      0<=t<=1 ;

将点带入圆的方程即可。 

注意:

有交点 0 <= t <= 1 ;

此题求覆盖的部分。 则 若求得 t  满足 ;

double  ask(double t){
        if(t < 0)  return 0 ;
        if(t > 1)  return 1 ;
        return t ;
}


const  double  eps = 1e-8 ;

int    dcmp(double x){
       if(fabs(x) < eps)  return 0 ;
       if(x < eps) return -1 ;
       return   1  ;
}

struct  point{
        double x , y ;
        void  mycin(){
              cin>>x>>y  ;
        }
};

double  ask(double x){
        if(x < 0)  return 0 ;
        if(x > 1)  return 1 ;
        return x ;
}

vector<pair<double , double> > g ;
void    circle_cross_line(point a , point b , point o , double r){
        double x0 = o.x , y0 = o.y ;
        double x1 = a.x , y1 = a.y ;
        double x2 = b.x , y2 = b.y ;
        double dx = x2 - x1 , dy = y2 - y1 ;
        double A = dx * dx + dy * dy ;
        double B = 2.0 * dx * (x1 - x0) + 2.0 * dy * (y1 - y0) ;
        double C = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0) - r * r ;
        double delta = B * B - 4 * A * C ;
        if(dcmp(delta) >= 0){
               double t1 =  (-B - sqrt(delta)) / (2.0*A) ;
               double t2 =  (-B + sqrt(delta)) / (2.0*A) ;
               double L = ask(t1) ;
               double R = ask(t2) ;
               if(L > R) swap(L , R) ;
               g.push_back( make_pair( L , R) ) ;
        }
}

point  o  , a , b ; double r ;

int  main(){
     int n ,  i  , j , k ;
     while(cin>>n && n){
          g.clear() ;
          a.mycin() ;  b.mycin() ;
          for(i = 1 ; i <= n ; i++){
               o.mycin() ;  cin>>r ;
               circle_cross_line(a , b , o , r) ;
          }

          if(g.size() == 0){
               puts("0.00") ; continue  ;
          }

          sort(g.begin() , g.end()) ;
          double L = g[0].first , R = g[0].second  , ans = 0.0  ;
          for(i = 1 ; i < g.size() ; i++){
               if(g[i].first > R){
                    ans += R - L ;
                    L = g[i].first ;
                    R = g[i].second ;
               }
               else R = max(R , g[i].second) ;
          }
          ans += R - L ;
          printf("%.2lf\n" , ans * 100.0) ;
     }
     return 0 ;
}








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值