HDU-4793 Collision 计算几何 解方程
題意
給我們兩個大小不同的圓的半徑小圓是實心的 大圓是空心的 然后給我們一個小球的半徑 小球的初始位置 還有飛碟在x方向和y方向上的速度 小球撞到內實心圓會能量不損失的反彈 問小球任何位置與大圓相交到完全出去的時間是多少
分析
幾何題 如何知道時間呢
如果小球與大圓相切或是無交點 那么小球所求的時間是0
如果小球與內圓相切或是無交點 那么小球所求的時間就是在內圓的交點處的兩個時間相減
如果小球與內院發(fā)生撞擊 那么小球回反射 由于能量不遞減 并且反射面是個球面 計算時間的范圍也是個球面那么也就相當于求怎么進來的大圓 就會反射出一個不同向的相同時間的軌跡 那么我們求出求進來大圓的時間 和小球撞擊內圓的時間 兩個作差乘2就能得到解
那么問題其實就相當于如何求出交點處的時間點是多少
我們知道小球的運動軌跡以及方程
x′=x0+vx?t
y′=y0+vy?t
還知道兩個圓的方程
x2+y2 = Rm2
x2+y2 = R2
由于初始位置,半徑已知所以其中唯一的變量就是t
那么我們把運動軌跡方程帶入到第一個圓的等式中 求得t 也就是小球經過第一個圓的交點處的t
(x0+vx?t)2+(y+vy?t)2 = (R+r)2
我們把運動軌跡方程代入到第二個圓的等式中 求得t也就是小球經過的第二個圓的交點處的t
(x0+vx?t)2+(y+vy?t)2 = (Rm+r)2
注意不同情況 我們需要不同的t去求結果
化簡可得
(vx2+vy2)?t2 +(2y?vy+2x?vx)?t - (R+r)2 =0
(vx2+vy2)?t2 +(2y?vy+2x?vx)?t - (Rm+r)2 =0<script type="math/tex" id="MathJax-Element-26">0</script>
那么這里就會產生一個問題 如果球軌跡所在直線和內圓相交 但是方向相反 由于代入等式是個二次方的
會無視方向 這里就需要判斷下
如果讓球動一點 球與內圓圓心的距離邊長了 那么就說明永不會相交 直接輸出0.000
所以 根據不同情況 解方程即可
CODE
#include<bits/stdc++.h> using namespace std; typedef long long ll; const double eps = 1e-8; double dis(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int main() {double Rm,R,r,x,y,vx,vy;while(~scanf("%lf%lf%lf%lf%lf%lf%lf",&Rm,&R,&r,&x,&y,&vx,&vy)){double ans,C = x*x+y*y-(R+r)*(R+r);double B = 2*y*vy+2*x*vx;double A = vy*vy+vx*vx;double jud = B*B-4*A*C;double x2 = x+vx,y2 = y+vy;if(dis(x2,y2,0,0)-dis(x,y,0,0)>eps){//判斷是否反向puts("0.000");continue;}if(jud-0<=eps){puts("0.000");continue;}double t1 = (-B-sqrt(jud))/(2*A);double t2 = (-B+sqrt(jud))/(2*A);double C2 = x*x+y*y-(Rm+r)*(Rm+r);double jud2 = B*B-4*A*C2;if(jud2-0<=eps){printf("%.3lf\n",t2-t1);continue;}double t3 = (-B-sqrt(jud2))/(2*A);printf("%.3lf\n",fabs((t1-t3)*2));}return 0 ; }總結
以上是生活随笔為你收集整理的HDU-4793 Collision 计算几何 解方程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSDN如何修改id号
- 下一篇: 软件编程常用语