SGU 110 三维计算几何 向量的灵活运用
来源:互联网 发布:智慧社区app源码下载 编辑:程序博客网 时间:2024/06/06 01:51
题意不解释.
思路:
我们用一个基点和一个方向向量来表示题目中的光线(射线) ,射线上的任何一点都可以用 base + t * dir 表示(t >= 0)
每次找到能射到的一个圆(与射线相交的圆,如果这种圆有多个就取距离最近的),找不到就停,然后反射,即维护一下base,dir。
向量活用:
1. 射线和圆求交点时把射线方程和圆方程联立,用向量的形式展开,再解个二元一次方程组即可。
2. 已知入射光线和法线,求反射光线
v1为入射光线,v2为法线。
把v1分解成v2方向和垂直v2方向,我们可以发现只要修改v1平行于v2的向量分量(把平行v2的那个向量分量大小不变,方向相反)。
以v2长度为基准,求出v1在v2方向的分量是v2长度的k倍。然后 反射光线v3 = v1 - v2*k*2;
k的求法可以先把v1投影到v2, 投影值为 v1*v2/|v2| (v1点乘v2, 除以v2的模), 然后 k = 投影值/|v2|;
#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>#include <vector>using namespace std;const double inf = 1e20;const double eps = 1e-10;struct point {double x, y, z;point(double x=0, double y=0, double z=0) : x(x), y(y), z(z) {}point operator +(point t) {return point(x+t.x, y+t.y, z+t.z);}point operator -(point t) {return point(x-t.x, y-t.y, z-t.z);}point operator *(double t) {return point(x*t, y*t, z*t);}point operator /(double t) {return point(x/t, y/t, z/t);}double operator *(point t) { // 向量点乘return x*t.x+y*t.y+z*t.z;}void in() {cin >> x >> y >> z;}};point cir[55], base, dir; // 圆心,基点,方向向量double R[55]; // 半径point Jiao; // 记录射线与圆的交点。vector <int> ans; // 记录路径int n;int cal() {double max_d = inf;double a, b, c;int i, ret = -1; // 射线上的点可以用 base + t * dir 表示 (t >= 0) for(i = 0; i < n; i++) { // (base + t*dir - cir[i]) == R[i]*R[i]; 解二元一次方程, 求出t。a = dir*dir;b = (base-cir[i])*dir*2;c = (base-cir[i])*(base-cir[i])-R[i]*R[i];double dlt = b*b-4*a*c;if(dlt < -eps) continue;dlt = sqrt(dlt);double t = (-b-dlt)/2/a; // 取小的那个,一定是碰到的if(t < eps) continue;point tp = base + dir * t;double d = (tp-base)*(tp-base);if(max_d > d + eps) {max_d = d; Jiao = tp; ret = i;}}return ret;}int main() {int i;cin >> n;for(i = 0; i < n; i++) {cir[i].in(); cin >> R[i];}base.in(); dir.in();ans.clear();int xx;dir = dir - base;for(xx = 1; xx <= 11; xx++) {int j = cal();if(j == -1) break;ans.push_back(j+1);point v = cir[j] - Jiao;dir = dir - v*(dir*v/(v*v))*2; // 向量的活用base = Jiao;}if(ans.size() >= 11) {for(i = 0; i < 10; i++)cout << ans[i] << " " ;cout << "etc." << endl;}else {for(i = 0; i < (int)ans.size(); i++) cout << ans[i] << " ";cout << endl;}return 0;}/*20 0 0 11 3 0 1-1 2 0 1 -1 020 0 0 15 0 0 1-99 1 0 999 0 01 21 2*/
- SGU 110 三维计算几何 向量的灵活运用
- sgu 110 Dungeon 三维计算几何
- 计算几何,三维向量的旋转
- SGU 110 计算几何
- SGU 110 Dungeon(计算几何)
- sgu-110 Dungeon(计算几何)
- SGU 110 Dungeon(计算几何)
- 计算几何三维模板
- 三维计算几何模板
- 三维计算几何模版
- 三维计算几何模板
- 几何中点(三维向量)、线、面的类
- poj 2957 计算几何向量的旋转
- 【计算几何】点与向量的表示
- 计算几何_向量的实现
- SGU 120 Arhipelago(计算几何)
- SGU 129 Inheritance(计算几何)
- SGU 120 Archipelago (计算几何)
- 观察者模式——Head First Design Patterns
- Harry Potter’s Exam (an application of Dijkstra algorithm)
- 程序题:Java代码实现1-1/2+1/3-1/4+...+1/100
- Android提交数据到服务器的两种方式四种方法
- java实现多线程的两种方法
- SGU 110 三维计算几何 向量的灵活运用
- Spring+Hibernate+struts Tiles布局框架
- ThinkPHP:关于import中@的说明
- android 中对apache httpclient及httpurlconnection的选择
- poj 1127 Jack Straws
- IOS成长之路-JSON解析
- hdu 4531 吉哥系列故事——乾坤大挪移
- ThinkPHP3.0,模板里面执行函数function的方法
- Project 3: Sort Poems