HDU 2912
直线关于球的多次反射,求最后一次反射点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath> using namespace std;
const double inf=1e10;
const double eps=1e-8;
struct point {
double x,y,z;
// point (double _x,double _y,double _z){ x=_x; y=_y; z=_z; };
};
struct sphe {
point cent;
double r;
};
struct vect {
point st,des;
};
sphe cir[110];
vect livc;
int n; point operator -(const point &u,const point &v){
point ret;
ret.x=u.x-v.x; ret.y=u.y-v.y; ret.z=u.z-v.z;
return ret;
} double dot(point x,point y){
return x.x*y.x+x.y*y.y+x.z*y.z;
} point xmulti(point u,point v){
point ret;
ret.x=(u.y*v.z-v.y*u.z);
ret.y=(u.z*v.x-u.x*v.z);
ret.z=(u.x*v.y-u.y*v.x);
return ret;
} double dis(point x,point y){
return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y)+(x.z-y.z)*(x.z-y.z));
} double vlen(point x){
return sqrt(x.x*x.x+x.y*x.y+x.z*x.z);
} point construct(){
point crop;
crop.x=crop.y=crop.z=0;
double stoc=inf; point tmpcrop; point foot,tmpfoot; bool flag; point tmp; int k;
while(true){
flag=false; stoc=inf;
for(int i=0;i<n;i++){
if(dot(livc.des-livc.st,cir[i].cent-livc.st)>=-eps){//判断圆是否与直线同向,通过点积判方向
double D=vlen(xmulti(livc.des-livc.st,cir[i].cent-livc.st))/dis(livc.st,livc.des);
// cout<<D<<' '<<i<<endl;
if(D-cir[i].r<=eps){ //半径小于D,相交
flag=true;
// cout<<"YES"<<endl;
double u=dot(cir[i].cent-livc.st,livc.des-livc.st)/(dis(livc.st,livc.des)*dis(livc.st,livc.des));
//计算垂足。可通过向量的比例所得方程,联合垂直点积为0的方程解得
tmpfoot=livc.st;
tmpfoot.x+=u*(livc.des.x-livc.st.x);
tmpfoot.y+=u*(livc.des.y-livc.st.y);
tmpfoot.z+=u*(livc.des.z-livc.st.z);
// cout<<tmpfoot.x<<' '<<tmpfoot.y<<' '<<tmpfoot.z<<' '<<endl;
u=sqrt((cir[i].r*cir[i].r-D*D))/dis(livc.st,livc.des); //计算交点。垂足到圆上交点方向与直线反方向相同
//通过两者距离比计算出向量的转化
tmpcrop=tmpfoot;
tmp=livc.st-livc.des;
tmpcrop.x+=tmp.x*u;
tmpcrop.y+=tmp.y*u;
tmpcrop.z+=tmp.z*u;
D=dis(tmpcrop,livc.st);
// cout<<D<<endl;
if(D<stoc){ //若与多个圆相交,选取较近的一个
stoc=D; crop=tmpcrop;
k=i;
}
}
}
}
if(!flag) return crop;
double tu=dot(livc.st-cir[k].cent,crop-cir[k].cent)/(dis(crop,cir[k].cent)*dis(crop,cir[k].cent));
tmpfoot=cir[k].cent; //计算反射线。直线st点关于交点与球心的直线 对称点作为反射线的des点
tmpfoot.x+=tu*(crop.x-cir[k].cent.x);
tmpfoot.y+=tu*(crop.y-cir[k].cent.y);
tmpfoot.z+=tu*(crop.z-cir[k].cent.z); //知直线st点到反射线des点的方向与st点到关于对称线垂足方向相同且为两倍
livc.des.x=((tmpfoot.x-livc.st.x)*2+livc.st.x); //通过这样可以求对称点
livc.des.y=((tmpfoot.y-livc.st.y)*2+livc.st.y);
livc.des.z=((tmpfoot.z-livc.st.z)*2+livc.st.z);
livc.st=crop;
// cout<<livc.des.x<<' '<<livc.des.x<<' '<<livc.des.x<<endl;
}
} int main(){
point tmp; double r;
while(scanf("%d",&n),n){
livc.st.x=livc.st.y=livc.st.z=0;
scanf("%lf%lf%lf",&tmp.x,&tmp.y,&tmp.z);
livc.des=tmp;
for(int i=0;i<n;i++){
scanf("%lf%lf%lf%lf",&cir[i].cent.x,&cir[i].cent.y,&cir[i].cent.z,&cir[i].r);
}
tmp=construct();
printf("%.4lf %.4lf %.4lf\n",tmp.x,tmp.y,tmp.z);
}
}
HDU 2912的更多相关文章
- Hdu 1079 Calendar Game
Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1079 一道博弈题.刚开始想用判断P点和N点的方法来打表,但无奈不知是哪里出错,总是WA.于是 ...
- HDU 5643 King's Game 打表
King's Game 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5643 Description In order to remember hi ...
- HDOJ 2111. Saving HDU 贪心 结构体排序
Saving HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- 【HDU 3037】Saving Beans Lucas定理模板
http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...
- hdu 4859 海岸线 Bestcoder Round 1
http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...
- HDU 4569 Special equations(取模)
Special equations Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u S ...
- HDU 4006The kth great number(K大数 +小顶堆)
The kth great number Time Limit:1000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64 ...
- HDU 1796How many integers can you find(容斥原理)
How many integers can you find Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%I64d ...
- hdu 4481 Time travel(高斯求期望)(转)
(转)http://blog.csdn.net/u013081425/article/details/39240021 http://acm.hdu.edu.cn/showproblem.php?pi ...
随机推荐
- 杂项-人物:Alan cooper
ylbtech-杂项-人物:Alan cooper Alan Cooper ,“VB之父”“交互设计之父”,荣获视窗先锋奖(Microsoft Windows Pioneer)和软件梦幻奖(Softw ...
- 267C
二分+高斯消元 我们利用物理里的势能来表示,每个点有一个势能h,再由流量守恒可以得到deg[x]*h[x]=sigma(h[y]) 如果x,y之间有边.这个式子是由流量守恒推出的,所以当x=1或n是不 ...
- iOS中的数据库—使用FMDB
一.回顾 iOS中的数据存储方式 1.XML属性列表(plist) 写入OC的一些基本数据类型,不是所有对象都可以写入 2.Preference(偏好设置) 本质还是通过“plist”来存储数据,但是 ...
- aspectC++常用命令
常用命令:1.ag++ main.cc //在工程目录下产生编译后的exe2.ag++ main.cc --weave_only //产生.acc 纯c++文件3.ag++ main.cc --gen ...
- JDK5.0新特性(静态导入、自动装箱/拆箱、增强for循环、可变参数、枚举、泛形)
JDK5中新增了很多新的java特性,利用这些新语法可以帮助开发人员编写出更加高效.清晰,安全的代码. 这些新特性主要有:1.静态导入2.自动装箱/拆箱3.增强for循环4.可变参数5.枚举6.泛型7 ...
- SiteMesh3使用实例和详解
一.SiteMesh介绍 SiteMesh是一个网页布局和修饰的框架,利用它可以将网页的内容和页面结构分离,以达到页面结构共享的目的.[来自百度百科] 通俗的理解就是,SiteMesh把页面中变化的和 ...
- C#Cookie操作类,删除Cookie,给Cookie赋值
using System;using System.Data;using System.Configuration;using System.Web;using System.Web.Security ...
- 使用idea 搭建一个 SpringBoot + Mybatis + logback 的maven 项
(注意项目名不能有大写......),把项目类型 改成 War 类型.(web项目) 使用 mybatis-generator 插件 生成 实体类 和 接口 在 resources 目录 中 新建一个 ...
- iOS - CocoaPods操作详解
在我们进行iOS应用开发的时候,肯定会用到很多的第三方类库,最常用AFNetworking,SDWebImage等等,当我们用到这个类库的时候,就要一个一个的去下载这个类库,如果这个类库中又用到了其他 ...
- 大白话理解promise对象
Promise 代表了未来某个将要发生的事件(通常是一个异步操作) Promise 是异步编程的解决方案,能够简化多层回调嵌套,代表了未来某个将要发生的事件.Promise是一个构造函数,本身有a ...