HDU 6559 The Tower(解析几何)

The Tower

Problem Description
The Tower shows a tall tower perched on the top of a rocky mountain. Lightning strikes, setting the building alight, and two people leap from 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.

在这里插入图片描述

Input
The first line contains testcase number T (T ≤ 1000), For each testcase the first line contains spaceseparated real numbers r and 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, vz (1 ≤ v2x + v2y + v2z ≤ 3 × 106). It is guaranteed that at time 0 the point is outside the cone and they will always collide.

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

Sample Input

2
1 2
1 1 1
-1.5 -1.5 -0.5
1 1
1 1 1
-1 -1 -1

Sample Output

Case 1: 0.3855293381
Case 2: 0.5857864376

题意
给出一个圆锥,底面圆心在原点,给出圆锥外一点(保证为圆锥外一点)。并给出该点在各个方向上的移动速度。求点撞击在圆锥面上时的时间t

题解
首先看了很久题,无法将其转化到平面通过几何方式求取(也可能是我想不到),所以只能通过解析几何的方式,通过方程求取。
由底面方程 x 2 + y 2 = r 2 x^2+y^2=r^2 x2+y2=r2和截面所做三角形
在这里插入图片描述
根据相似三角形,求出 r ′ = r ( h − z ) h r'=\cfrac{r(h-z)}{h} r=hr(hz)
故圆锥面方程为 x 2 + y 2 = r ′ 2 = r 2 ( h − z ) 2 h 2 , z ∈ [ 0 , h ] x^2+y^2=r'^2=\cfrac{r^2(h-z)^2}{h^2},z\in[0,h] x2+y2=r2=h2r2(hz)2z[0,h]

由给出的点坐标 ( x 0 , y 0 , z 0 ) (x_0,y_0,z_0) (x0,y0,z0)以及对应方向运动速度 ( v x , v y , v z ) (v_x,v_y,v_z) (vx,vy,vz)
我们设撞击时间为t
因此撞击点坐标为 ( x 0 + v x t , y 0 + v y t , z 0 + v z t ) (x_0+v_xt,y_0+v_yt,z_0+v_zt) (x0+vxt,y0+vyt,z0+vzt)
将撞击点坐标带入圆锥面方程,得到一个只关于t的一元二次方程,太长了,恶心,不往上打了。
根据方程解出t的值 t 1 , t 2 ( t 1 &lt; t 2 ) t_1,t_2(t_1&lt;t_2) t1,t2t1<t2
要注意的是,我们写出的圆锥方程是 z ∈ [ 0 , h ] z\in[0,h] z[0,h]的,而在程序中没有表示所以是上下两个圆锥底对底拼在一起的,因此我们得到两个撞击点。
因为保证了撞击点是存在的,所以我们只需要判断,t1时的撞击点是否满足 t 1 &gt; 0 且 z 0 + v z t 1 ∈ [ 0 , h ] t_1&gt;0且z_0+v_zt_1\in[0,h] t1>0z0+vzt1[0,h]
满足则输出 t 1 t_1 t1,不满足则为 t 2 t_2 t2

代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <set>
#include <cmath>

using namespace std;
#define me(x,y) memset(x,y,sizeof x)
#define MIN(x,y) x < y ? x : y
#define MAX(x,y) x > y ? x : y

typedef long long ll;
typedef unsigned long long ull;

const int maxn = 1e5+10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const double eps = 1e-09;
const double PI = acos(-1.0);

int main(){
    int t,ca=1;cin>>t;
    while(t--){
        double r,h,x0,y0,z0,vx,vy,vz;
        scanf("%lf%lf",&r,&h);
        scanf("%lf%lf%lf",&x0,&y0,&z0);
        scanf("%lf%lf%lf",&vx,&vy,&vz);
        double a=vx*vx*h*h+vy*vy*h*h-vz*vz*r*r;
        double b=2*x0*vx*h*h+2*y0*vy*h*h+2*h*vz*r*r-2*z0*vz*r*r;
        double c=x0*x0*h*h+y0*y0*h*h-r*r*h*h+2*h*z0*r*r-z0*z0*r*r;
        double x1=(-b+sqrt(b*b-4*a*c))/(2*a);
        double x2=(-b-sqrt(b*b-4*a*c))/(2*a);
//        printf("%lf %lf %lf\n",a,b,c);
//        printf("%lf %lf\n",x1,x2);
        if(x1>x2) swap(x1,x2);
        printf("Case %d: ",ca++);
        if(x1 < 0) printf("%.10lf\n",x2);
        else{
            double z1=z0+vz*x1;
            if(z1<0 || z1>h) printf("%.10lf\n",x2);
            else printf("%.10lf\n",x1);
        }
    }
    return 0;
}

/*
 
*/
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值