HDU - 1174:爆头 (三维平面点到射线的距离)
pro:给定警察的射击位置,设计方向,敌人的位置,敌人的头部半径,问子弹是否可以射到头部。
sol:即问头部中点到子弹射线的距离是否小于等于头部半径。
和二维的点到直线一样的操作。 det/dot; 用平行四边形面积/底。 那么唯一的问题就是三维向量的det怎么求。 如图:
由于是射线,还要判定是否同向。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=200010; struct point3 { double x,y,z; point3(){} point3(double xx,double yy,double zz):x(xx),y(yy),z(zz){} }; point3 operator -(point3 a,point3 b){ return point3(a.x-b.x,a.y-b.y,a.z-b.z);} point3 A,B,C; double det(point3 a,point3 b){ double x=a.x*b.y-a.y*b.x; double y=a.x*b.z-a.z*b.x; double z=a.y*b.z-a.z*b.y; return sqrt(x*x+y*y+z*z); } double dot(point3 a,point3 b){ return a.x*b.x+a.y*b.y+a.z*b.z; } int main() { int T; double H1,H2,R1,R2; scanf("%d",&T); while(T--){ scanf("%lf%lf%lf%lf%lf",&H1,&R1,&A.x,&A.y,&A.z); scanf("%lf%lf%lf%lf%lf",&H2,&R2,&B.x,&B.y,&B.z); scanf("%lf%lf%lf",&C.x,&C.y,&C.z); A.z+=H1-R1; B.z+=H2*0.9-R2; double ans=det(A-B,C)/sqrt(dot(C,C)); if(dot(A-B,C)>=0&&ans<=R1) puts("YES"); else puts("NO"); } return 0; }
It is your time to fight!