HDU2912 Spherical Mirrors 计算几何

mac2022-06-30  93

题意:求一条射线经过一系列球反射后的反射点

分析:从起点出发,求出射线与球的最近交点,然后更改反射线为入射线循环找射线与球的最近交点,直到没有球与射线相交。

#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 x * h.x + y * h.y + 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); } point operator * (point b){ // 叉乘 return point(y * b.z - b.y * z, z * b.x - b.z * x, x * b.y - b.x * y); } double len2() const { return x * x + y * y + z * z; } double len() const { return sqrt(len2()); } point turnlen( double l) const { // 改变长度 double r = l / len(); return point(x * r,y * r,z * r); } void input() { scanf( " %lf%lf%lf " , & x, & y, & z); }}p1,p2,ans; struct sphere{ point c; double r; void input(){ c.input(); scanf( " %lf " , & r); }}sph[ 110 ]; int n; const double eps = 1e - 8 ; int sgn( double x){ if (fabs(x) < eps) return 0 ; return x > 0 ? 1 : - 1 ;} bool intersection(sphere s,point p1,point p2,point & c) // 求p2-p1与球s的交点c { double d = ((p1 - s.c) * (p2 - s.c)).len() / (p1 - p2).len(); // 球心到p2-p1的距离 if (sgn(d - s.r) >= 0 ) return false ; //pp 球心与直线p2-p1的垂足 point pp = (sgn(d) == 0 ? s.c:s.c + ((p1 - s.c) * (p2 - s.c) * (p1 - p2)).turnlen(d) );   if (sgn((pp - p1) ^ (p2 - p1)) <= 0 ) // 如果pp在p2-p1的反向延长线上 返回false return false ; c = pp + (p1 - p2).turnlen(sqrt(s.r * s.r - d * d)); return true ;}point reflection(point p1,point rep,point c) // p1关于rep-c的对称点 { double d = ((rep - p1) * (c - p1)).len() / (rep - c).len(); return p1 + ((rep - p1) * (c - p1) * (rep - c)).turnlen(d * 2.0 );} void compute(){ while ( true ){ point c; int k =- 1 ; for ( int i = 0 ;i < n;i ++ ) // 找到与射线相交的最近的球 { point tmp; if (intersection(sph[i],p1,p2,tmp)){ if (k ==- 1 || sgn((tmp - p1).len() - (c - p1).len()) < 0 ){ c = tmp; k = i; } } } if (k ==- 1 ) break ; p2 = reflection(p1,sph[k].c,c); // p2反射线上一点 p1 = c; // 反射点 } ans = p1;} int main(){ while (scanf( " %d " , & n),n) { p1 = point(); p2.input(); for ( int i = 0 ;i < n;i ++ ) sph[i].input(); compute(); printf( " %.8lf %.8lf %.8lf\n " ,ans.x,ans.y,ans.z); } return 0 ;}

 

转载于:https://www.cnblogs.com/DreamUp/archive/2010/08/28/1811157.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)