这道题是计算几何,这是写的第一道计算几何,主要是难在如何求入射光线的反射光线。

我们可以用入射光线 - 入射光线在法线(交点到圆心的向量)上的投影*2 来计算反射光线,自己画一个图,非常清晰明了。

具体到程序里,我们可以 v2 = v1 - fa / Length(fa) * 2 * ( Dot(v1, fa) / Length(fa)) 来求,简单来说就是用内积(点积)求出入射光线在法线上的长度,然后用法线的单位向量乘这个长度就可以了。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cmath>
#define N 55
#define inf 0x7f7f7f7f
using namespace std; struct Point3
{
double x, y, z;
Point3(double x=, double y=, double z=):x(x), y(y), z(z) { }
};
typedef Point3 Vector3;
const double eps = 1e-; int dcmp(double x)
{
if (fabs(x) < eps) return ;
else return x < ? - : ;
} int n;
double r[N];
Point3 Begin, circle[N];
Vector3 Direct; Vector3 operator + (Vector3 A, Vector3 B) { return Vector3(A.x+B.x, A.y+B.y, A.z+B.z); }
Vector3 operator - (Point3 A, Point3 B) { return Vector3(A.x-B.x, A.y-B.y, A.z-B.z); }
Vector3 operator * (Vector3 A, double p) { return Vector3(A.x*p, A.y*p, A.z*p); }
Vector3 operator / (Vector3 A, double p) { return Vector3(A.x/p, A.y/p, A.z/p); } double min(double x, double y) { return x < y ? x : y; } double Dot (Vector3 A, Vector3 B) { return A.x*B.x + A.y*B.y + A.z*B.z; }
double Length (Vector3 A) { return sqrt(Dot(A, A)); }
double Angle (Vector3 A, Vector3 B) { return acos(Dot(A, B) / Length(A) / Length(B)); }
Vector3 Cross (Vector3 A, Vector3 B) { return Vector3(A.y*B.z - A.z*B.y, A.z*B.x - A.x*B.z, A.y*B.z - A.z*B.y); }
double disPointLine(Point3 P, Point3 A, Point3 B)
{
Vector3 v1, v2;
v1 = B - A; v2 = P - A;
return Length(Cross(v1, v2)) / Length(v1);
} int main()
{
scanf("%d", &n);
double x, y, z;
for (int i = ; i <= n; ++i)
{
scanf("%lf%lf%lf%lf", &x, &y, &z, &r[i]);
circle[i] = Point3(x, y, z);
}
scanf("%lf%lf%lf", &x, &y, &z); Begin = Point3(x, y ,z);
scanf("%lf%lf%lf", &x, &y, &z); Direct = Point3(x, y, z) - Begin;
int nowcircle = ;
for (int w = ; w <= ; ++w)
{
int nextcircle = ;
double mindis = inf;
for (int i = ; i <= n; ++i)
{
if (i == nowcircle) continue;
double a, b, c;
Point3 nc = circle[i];
a = Direct.x*Direct.x + Direct.y*Direct.y + Direct.z*Direct.z;
b = * ((Begin.x-nc.x) * Direct.x + (Begin.y-nc.y)*Direct.y + (Begin.z-nc.z)*Direct.z);
c = (Begin.x-nc.x)*(Begin.x-nc.x) + (Begin.y-nc.y)*(Begin.y-nc.y) + (Begin.z-nc.z)*(Begin.z-nc.z) - r[i]*r[i];
double delta;
delta = b*b - *a*c;
if (delta < ) continue;
double ans1, ans2;
ans1 = (-b + sqrt(delta)) / (*a);
ans2 = (-b - sqrt(delta)) / (*a);
if (dcmp(ans1) < && dcmp(ans2) < ) continue;
else if (dcmp(ans1) < && ans2 < mindis)
{
mindis = ans2;
nextcircle = i;
}
else if (dcmp(ans2) < && ans1 < mindis)
{
mindis = ans1;
nextcircle = i;
}
else if (min(ans1, ans2) < mindis)
{
mindis = min(ans1, ans2);
nextcircle = i;
}
}
if (!nextcircle) break;
else if (w == )
{
printf(" etc.");
break;
}
else
{
if (w == ) printf("%d", nextcircle);
else printf(" %d", nextcircle);
Point3 jiao;
Vector3 v1, v2, fa;
jiao = Begin + Direct*mindis; v1 = Direct;
fa = circle[nextcircle] - jiao;
v2 = (fa / Length(fa)) * ( * Dot(v1, fa) / Length(fa));
nowcircle = nextcircle;
Begin = jiao; Direct = v1 - v2;
}
}
printf("\n");
}

sgu 110 Dungeon的更多相关文章

  1. SGU 110. Dungeon 计算几何 难度:3

    110. Dungeon time limit per test: 0.25 sec. memory limit per test: 4096 KB The mission of space expl ...

  2. SGU 分类

    http://acm.sgu.ru/problemset.php?contest=0&volume=1 101 Domino 欧拉路 102 Coprime 枚举/数学方法 103 Traff ...

  3. PostMan的在线安装和简单使用

    Postman是一款很流行的WEB接口测试工具,因其强大的功能及清新的界面,赢得许多测试及开发者的喜爱.   1.PostMan的在线安装 因google退出中国,使得chrome上的扩展插件无法在线 ...

  4. SGU Volume 1

    SGU 解题报告(持续更新中...Ctrl+A可看题目类型): SGU101.Domino(多米诺骨牌)------------★★★type:图 SGU102.Coprimes(互质的数) SGU1 ...

  5. [LeetCode] Dungeon Game 地牢游戏

    The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. ...

  6. POJ 2251 Dungeon Master(3D迷宫 bfs)

    传送门 Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 28416   Accepted: 11 ...

  7. sgu 240 Runaway (spfa)

    题意:N点M边的无向图,边上有线性不下降的温度,给固定入口S,有E个出口.逃出去,使最大承受温度最小.输出该温度,若该温度超过H,输出-1. 羞涩的题意 显然N*H的复杂度dp[n][h]表示到达n最 ...

  8. [变]C#谜题(1-10)表达式篇

    [变]C#谜题(1-10)表达式篇 最近偶然发现了<Java谜题>,很有意思,于是转到C#上研究一下. 本篇是关于表达式的一些内容. 谜题1:奇数性(负数的取模运算) 下面的方法意图确定它 ...

  9. [No00006D]下载离线版的github for windows【以Github for Windows 3.0.110.为例】

    目录 先上地址后讲原理: 原理: 11个目录的文件怎么一口气下载呢? 最后,把下好的文件批量名,同时将GitHub.exe.manifest也放到软件根目录下(与GitHub.exe同级): 今后的猜 ...

随机推荐

  1. eclipse创建maven模块工程

    创建maven模块项目,可以使用eclipse工具来完成. 1.创建父工程,注意,要选择maven-archetype-site-simple new --> maven project 填写项 ...

  2. paip.输入法编程---词频顺序order by py

    paip.输入法编程---词频顺序order by py 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn ...

  3. [Node.js] Creating Demo APIs with json-server

    json-server makes it extremely easy to setup robust JSON apis to use for demos and proof of concepts ...

  4. ios开发——实用技术篇&网络音频播放

    网络音频播放 在日常的iOS开发中,我们通常会遇到媒体播放的问题,XCode中已经为我们提供了功能非常强大的AVFoundation框架和 MediaPlayer框架.其中AVFoundation框架 ...

  5. 深刻理解Python中的元类(metaclass)

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...

  6. STL——迭代器的概念

    迭代器是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物. 1 迭代器设计思维——STL关键所在 不论是泛型思维或STL的实际运用,迭代器都扮演这重要的角色.STL的中心思想在于:将数 ...

  7. STL——空间的配置和释放std::alloc(第一级配置器和第二级配置器)

    1 空间的配置和释放,std::alloc 对象构造前的空间配置和对象析构后的空间释放,由<stl_alloc.h>负责,SGI对此的设计哲学如下: 向system heap要求空间 考虑 ...

  8. 信号之sigsetjmp和siglongjmp函数

    在信号处理程序中经常调用longjmp函数以返回到程序的主循环中,而不是从该处理程序返回. 但是,调用longjmp有一个问题.当捕捉到一个信号时,进入信号捕捉函数,此时当前信号被自动地加到进程的信号 ...

  9. android startActivityForResult(Intent intent, int requestCode) 整理与总结! .

    假设有两个Activity,主界面A,功能界面B,由A启动B,并传数据给B,B在经过处理后把数据传回给A. 先是A传B: Bundle bundle = new Bundle();bundle.put ...

  10. 【转】C语言 字符数组与字符串

    原文:http://blog.csdn.net/metasearch/article/details/2856097 在C语言编程中,当我们声明一个字符串数组的时候,常常需要把它初始化为空串.总结起来 ...