本文主要是介绍圆与线段的交点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
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 ;
}
这篇关于圆与线段的交点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!