对于速度V的方向有三种情况,可用V与ABCD面法向量的点积判断:1 V指向ABCD面外侧,或V与ABCD面平行,不可能进球;2 ball在ABCD面内侧,不可能进球;3 ball在ABCD面上,当且仅当 P在多边形ABCD内(不包括边界)才进球4 ball在ABCD面外侧,当且仅当 直线P+xV与ABCD面的交点Q在多边形ABCD内(不包括边界)才进球
代码 #include < iostream > #include < cmath > using namespace std; struct point{ double x,y,z; point( double xx = 0 , double yy = 0 , double zz = 0 ){ // 构造函数 x = xx,y = yy,z = zz; } point operator * ( double h){ return point(x * h,y * h,z * h); } double operator * (point h){ // 点乘 return this -> x * h.x + this -> y * h.y + this -> z * h.z; } point operator + (point h){ return point(x + h.x,y + h.y,z + h.z); } point operator - (point h){ return point(x - h.x,y - h.y,z - h.z); } // 所有class method必须有匹配的左值类型进行调用而friend则无需这样 point friend operator % (point a,point b){ // 叉乘 return point(a.y * b.z - b.y * a.z, a.z * b.x - b.z * a.x, a.x * b.y - b.x * a.y); } double len2(){ return x * x + y * y + z * z; } double len(){ return sqrt(len2()); } void in (){ scanf( " %lf%lf%lf " , & x, & y, & z); } void show(){ printf( " %.2lf %.2lf %.2lf\n " ,x,y,z); }}ball,v,a,b,c,d,e,f,g,h;point dc,da,dh,aim; // dh是dc和da的叉乘,也就是面abcd向外的法向量; // aim是球最后飞到的位置,当然设置到无穷远处比较好的。 const double eps = 1e - 4 ; int sign( double x){ if (fabs(x) < eps) return 0 ; return x > 0 ? 1 : - 1 ;}point intersection(point l1,point l2,point s1,point s2,point s3) // 矢量与面的交点 { point ret = (s3 - s2) % (s1 - s2); // 法向量 double t = ret * (s1 - l1) / (ret * (l2 - l1)); ret.x = l1.x + (l2.x - l1.x) * t; ret.y = l1.y + (l2.y - l1.y) * t; ret.z = l1.z + (l2.z - l1.z) * t; return ret;} double area(point a,point b,point c){ // 三个点求面积 return ((b - a) % (c - a)).len() / 2.0 ;} bool ok(point pcro){ // 判断点是否位于矩形内 double s1,s2 = 0 ,tmp; s1 = (b - a).len() * (d - a).len(); s2 = 0 ; tmp = area(pcro,a,d); s2 += tmp; if (sign(tmp) == 0 ) return false ; tmp = area(pcro,d,c); s2 += tmp; if (sign(tmp) == 0 ) return false ; tmp = area(pcro,c,b); s2 += tmp; if (sign(tmp) == 0 ) return false ; tmp = area(pcro,b,a); s2 += tmp; if (sign(tmp) == 0 ) return false ; if (sign(s1 - s2) == 0 ) return true ; return false ;} int main(){ int cas,ca; scanf( " %d " , & cas); for (ca = 1 ;ca <= cas;ca ++ ) { ball. in (); v. in (); a. in (); b. in (); c. in (); d. in (); e. in (); f. in (); g. in (); h. in (); dc = c - d; da = a - d; dh = dc % da; // 以d点作为参考点 aim = ball + v; printf( " Case %d: " ,ca); // 不动球,平行了,或者飞出来的球,球在平面的另一侧,无效 if (sign(v.len() == 0 ) || sign(v * dh) >= 0 || ((ball - d) * dh) < 0 ) { puts( " Intelligent Larrionda!!! " ); continue ; } point pcro = intersection(ball,aim,a,b,c); puts(ok(pcro) ? " Stupid Larrionda!!! " : " Intelligent Larrionda!!! " ); } return 0 ;}两点:
1.c++ operator定义为friend function请看博文http://blog.csdn.net/frankie110/archive/2009/12/30/5108373.aspx
2.当ball在ABCD面上时,intersection函数中的t等于0。 t代表的是什么?
t代表的是(ball到平面的距离)与(v在平面法向量上的投影)的比值。
转载于:https://www.cnblogs.com/DreamUp/archive/2010/08/21/1805526.html
