简单的题意,要注意z2 = h2*0.9-r2
#include <iostream> #include <cmath> #include <vector> #include <string.h> #include <stdlib.h> #include <algorithm> using namespace std; #define MAX_N 110 /*------------------常量区-------------------*/ const double INF = 1e10; // 无穷大 const double EPS = 1e-8; // 计算精度 const double PI = acos(-1.0);// PI const int PINXING = 0; // 平行 const int XIANGJIAO = 1; // 相交 const int XIANGLI = 0; // 相离 const int GONGXIAN = 2; // 共线 const int CHONGDIE = -1; // 重叠 const int INSIDE = 1; // 点在图形内部 const int OUTSIDE = 0; // 点在图形外部 const int BORDER = 2; // 点在图形边界 /*-----------------类型定义区----------------*/ struct Point { // 二维点或矢量 double x, y; //double angle, dis; Point() {} Point(double x0, double y0): x(x0), y(y0) {} void read() { scanf("%lf%lf",&x,&y); } }; struct Line { // 二维的直线或线段 Point p1, p2; Line() {} Line(Point p10, Point p20): p1(p10), p2(p20) {} void read() { scanf("%lf%lf%lf%lf",&p1.x,&p1.y,&p2.x,&p2.y); } }; struct Rect { // 用长宽表示矩形的方法 w, h分别表示宽度和高度 double w, h; Rect() {} Rect(double _w,double _h) : w(_w),h(_h) {} }; struct Rect_2 { // 表示矩形,左下角坐标是(xl, yl),右上角坐标是(xh, yh) double xl, yl, xh, yh; Rect_2() {} Rect_2(double _xl,double _yl,double _xh,double _yh) : xl(_xl),yl(_yl),xh(_xh),yh(_yh) {} }; struct Circle { //圆 Point c; double r; Circle() {} Circle(Point _c,double _r) :c(_c),r(_r) {} }; typedef vector<Point> Polygon; // 二维多边形 typedef vector<Point> Points; // 二维点集 /*-------------------基本函数区---------------------*/ inline double max(double x,double y) { return x > y ? x : y; } inline double min(double x, double y) { return x > y ? y : x; } inline bool ZERO(double x) // x == 0 { return (fabs(x) < EPS); } inline bool ZERO(Point p) // p == 0 { return (ZERO(p.x) && ZERO(p.y)); } inline bool EQ(double x, double y) // eqaul, x == y { return (fabs(x - y) < EPS); } inline bool NEQ(double x, double y) // not equal, x != y { return (fabs(x - y) >= EPS); } inline bool LT(double x, double y) // less than, x < y { return ( NEQ(x, y) && (x < y) ); } inline bool GT(double x, double y) // greater than, x > y { return ( NEQ(x, y) && (x > y) ); } inline bool LEQ(double x, double y) // less equal, x <= y { return ( EQ(x, y) || (x < y) ); } inline bool GEQ(double x, double y) // greater equal, x >= y { return ( EQ(x, y) || (x > y) ); } // 输出浮点数前,防止输出-0.00调用该函数进行修正! inline double FIX(double x) { return (fabs(x) < EPS) ? 0 : x; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //-------------------3D 区域----------------------------// struct Point3D { //三维点或矢量 double x, y, z; Point3D() {} Point3D(double x0, double y0, double z0): x(x0), y(y0), z(z0) {} }; struct Line3D { // 三维的直线或线段 Point3D p1, p2; Line3D() {} Line3D(Point3D p10, Point3D p20): p1(p10), p2(p20) {} }; inline bool ZERO(Point3D p) // p == 0 { return (ZERO(p.x) && ZERO(p.y) && ZERO(p.z)); } ////////////////////////////////////////////////////////////////////////////////////// //三维矢量运算 bool operator==(Point3D p1, Point3D p2) { return ( EQ(p1.x, p2.x) && EQ(p1.y, p2.y) && EQ(p1.z, p2.z) ); } bool operator<(Point3D p1, Point3D p2) { if (NEQ(p1.x, p2.x)) { return (p1.x < p2.x); } else if (NEQ(p1.y, p2.y)) { return (p1.y < p2.y); } else { return (p1.z < p2.z); } } Point3D operator+(Point3D p1, Point3D p2) { return Point3D(p1.x + p2.x, p1.y + p2.y, p1.z + p2.z); } Point3D operator-(Point3D p1, Point3D p2) { return Point3D(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z); } Point3D operator*(Point3D p1, Point3D p2) // 计算叉乘 p1 x p2 { return Point3D(p1.y * p2.z - p1.z * p2.y, p1.z * p2.x - p1.x * p2.z, p1.x * p2.y - p1.y * p2.x ); } double operator&(Point3D p1, Point3D p2) { // 计算点积 p1·p2 return (p1.x * p2.x + p1.y * p2.y + p1.z * p2.z); } double Norm(Point3D p) // 计算矢量p的模 { return sqrt(p.x * p.x + p.y * p.y + p.z * p.z); } //求三维空间中两点间的距离 double Dis(Point3D p1, Point3D p2) { return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z)); } // 求三维空间中点到直线的距离 double Dis(Point3D p, Line3D L) { if(L.p1==L.p2) return Dis(p, L.p1); return Norm((p - L.p1) * (L.p2 - L.p1)) / Norm(L.p2 - L.p1); } bool OnLine(Point3D p, Line3D L) // 判断三维空间中点p是否在直线L上 { if(L.p1==L.p2 && p==L.p1) return true;//共点时,返回true return ZERO( (p - L.p1) * (L.p2 - L.p1) ); } bool OnLineSeg(Point3D p, Line3D L) // 判断三维空间中点p是否在线段l上 { return ( ZERO((L.p1 - p) * (L.p2 - p)) && EQ( Norm(p - L.p1) + Norm(p - L.p2), Norm(L.p2 - L.p1)) ); } ////////////////////////////////////////////////////////////////////////////////////// /*---------------------代码区---------------------------*/ int main(int argc, const char * argv[]) { int T; cin>>T; while(T--) { double h1,r1,x1,y1,z1; cin>>h1>>r1>>x1>>y1>>z1; z1 += h1-r1; double h2,r2,x2,y2,z2; double x3,y3,z3; cin>>h2>>r2>>x2>>y2>>z2; cin>>x3>>y3>>z3; z2 += h2*0.9-r2; Point3D p(x1,y1,z1); Point3D p1(x2,y2,z2),p2(x2+100*x3,y2+100*y3,z2+100*z3); if( LEQ(Dis(p, p1), r1) ) { printf("YES "); continue; } Line3D l(p1,p2); double dis=Dis(p,l); if( GT( dis,r1 ) ) { printf("NO "); } else { Point3D p3(x3,y3,z3); //然后判断射线与球相交. if( LEQ( ((p1-p)&p3),0 ) ) { printf("YES "); } else printf("NO "); } } return 0; }