2018 CCPC 吉林 E (THE TOWER) 计算几何

问题 E: THE TOWER

时间限制: 1 Sec 内存限制: 128 MB Special Judge

题目描述
The Tower shows atall tower perched on the top of a rocky mountain. Lightning strikes, setting the building alight, and two people leap frnm the windows, head first and arms outstretched.
It is a scene of chaos and destruction.
There is a cone tower with base center at (0, 0, 0), base radius r and apex (0, 0, h) . At time 0 , a point located at ( x0 ,y0, z0) with velocity (vx,vy,vz). What time will they collide? Here is the cone tower.

在这里插入图片描述
输入
The first line contains testcase number T (T≤1000), For each testcase the first line contains spaceseparated real numbers rand h (1≤r,h≤1000) the base radius and the cone height correspondingly.
For each testcase the second line contains three real numbers x0 ,y0, z0 (0≤|x0|,|y0|,z0≤1000). For each testcase the third line contains three real numbers vx,vy,vx . It is guaranteed that at time 0 the point is outside the cone and they will always collide.
在这里插入图片描述

输出
For each testcase print Case i: and then print the answer in one line, with absolute or relative error not exceeding 10-6

样例输入
2
1 2
1 1 1
-1.5 -1.5 -0.5
1 1
1 1 1
-1 -1 -1
样例输出
Case 1: 0.3855293381
Case 2: 0.5857864376


思路:

(x+tvx)2+(y+tvy)2r2=[h(z+tvz)]2h2 \frac{\left(x+t v_{x}\right)^{2}+(y+t v_y)^{2}}{r^{2}}=\frac{\left[h-\left(z+t v_{z}\right)\right]^{2}}{h^{2}}
令:K=hzK=h-z 有 ,[h(z+tvz)]2=[(hz)tvz]2=K22Ktvz+t2vz2[h-(z+t v_ z)]^{2}=\left[(h-z)-tv_{z}\right]^{2}=K^{2}-2 K t v_{z}+t^{2} v_{z}^{2}
令:C=r2h2 C = \frac{r^{2}}{h^{2}}
化简得:
x2+y2+2t(xvx+yvy)+t2(vx2+vy2)=CK22CKvzt+Ct2vz2 x^{2}+y^{2}+2 t\left(x v_{x}+y v_{y}\right)+t^{2}\left(v_{x}^{2}+v_{y}^{2}\right)=C K^{2}-2 C K v_{z} t+C t^{2} v_{z}^{2}
转换为一元二次方程求解 t
A=vx2+vy2Cvz2A=v_{x}^{2}+v_{y}^{2}-C v_{z}^{2}

B=2(xvx+yvy+CKvz)B=2 *( xv_{x}+y v_{y}+C K v_{z} )

C=x2+y2CK2C=x^{2}+y^{2} - C K^{2}

ans 取最小的 t 就可以了,大的那个 t 是第二次接触圆锥面的时间

#include<bits/stdc++.h>
using namespace std;
double h, r, x, y, z, vx, vy, vz;
int main(){
    int T;
    scanf("%d",&T);
    for (int CS = 1; CS <= T; CS++) {
        scanf("%lf%lf", &r, &h);
        scanf("%lf%lf%lf", &x, &y, &z);
        scanf("%lf%lf%lf", &vx, &vy, &vz);
        z -= h;
        double K = r/h;
        double A = vx*vx+vy*vy-K*K*vz*vz;
        double B = 2*(vx*x+vy*y-K*K*vz*z);
        double C = x*x+y*y-K*K*z*z;
        double ans = (-B - sqrt(B*B-4*A*C)) / 2 / A;
        printf("Case %d: %.10lf\n", CS, ans);
    }
}

注意代码里 z = z - h
公式里是 z = h - z

posted @ 2019-05-03 22:51  Coder_L  阅读(237)  评论(0编辑  收藏  举报