sgu-265. Wizards
2015-06-24 14:12
281 查看
题目大意:
空间直角坐标系中有M(M<=100000)M(M<=100000)个点,然后有一个操作集合,集合大小为N(N<=1000)N(N<=1000),操作包括平移,关于原点放缩,还有绕向量旋转。要你求出所有点操作完后的坐标。~
~
~
解题思路:
显然这需要把NN个操作都变为一个矩阵或者什么别的东西,使得最后计算答案的时候只需要进行一次操作就行了。具体的操作方法再次不赘述了,主要是点绕向量旋转是一个问题。
我们令向量为t→\overrightarrow{t},点为pp,因为题目保证t→\overrightarrow{t}是以原点为起点,然后我们只要求出pp对于t→\overrightarrow{t}的垂直向量P→\overrightarrow{P}然后叉乘得出垂直向量g→\overrightarrow{g},然后将g→\overrightarrow{g}调整成和t→\overrightarrow{t}长度相同,然后最后的到得点pp为g→∗sin(α)+P→∗cos(α)+tmp−→−\overrightarrow{g}*sin(\alpha)+\overrightarrow{P}*cos(\alpha)+\overrightarrow{tmp}
AC代码:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> using namespace std; const double PI=acos(-1); struct Point { double x,y,z; Point(){x=y=z=0;}; Point(double x_,double y_,double z_) {x=x_,y=y_,z=z_;} double operator^(Point a1) {return x*a1.x+y*a1.y+z*a1.z;} Point operator-(Point a1) {return Point(x-a1.x,y-a1.y,z-a1.z);} Point operator+(Point a1) {return Point(x+a1.x,y+a1.y,z+a1.z);} Point operator*(Point a1) {return Point(y*a1.z-a1.y*z,z*a1.x-a1.z*x,x*a1.y-a1.x*y);} Point operator*(double a1) {return Point(x*a1,y*a1,z*a1);} void scanling(double a,double b,double c) {x*=a,y*=b,z*=c;} double Lenth() {return sqrt(x*x+y*y+z*z);} void rotate(Point a1,double X) { Point cnt=Point(x,y,z); Point tmp=a1*((cnt^a1)/(a1^a1)); cnt=cnt-tmp; Point M=a1*cnt; if(M.Lenth()<=1e-10) return; M=M*(cnt.Lenth()/M.Lenth()); x=cnt.x*cos(X)+M.x*sin(X)+tmp.x; y=cnt.y*cos(X)+M.y*sin(X)+tmp.y; z=cnt.z*cos(X)+M.z*sin(X)+tmp.z; } }; void Readch(char &ch) { for(ch=getchar();ch=='\n' || ch=='\r' || ch==' ';ch=getchar()); return; } int main() { char ch='\0'; int N; scanf("%d",&N); struct Point P[4]; P[1]=Point(1,0,0);P[2]=Point(0,1,0),P[3]=Point(0,0,1); for(int i=1;i<=N;i++) { Readch(ch); if(ch=='T') { double a,b,c; scanf("%lf%lf%lf",&a,&b,&c); P[0]=P[0]+Point(a,b,c); } else if(ch=='S') { double a,b,c; scanf("%lf%lf%lf",&a,&b,&c); for(int i=0;i<=3;i++) P[i].scanling(a,b,c); } else if(ch=='R') { double a,b,c,d; scanf("%lf%lf%lf%lf",&a,&b,&c,&d); d=d/180*PI; for(int j=0;j<=3;j++) P[j].rotate(Point(a,b,c),d); } } int M; scanf("%d",&M); for(int i=1;i<=M;i++) { double a,b,c; scanf("%lf%lf%lf",&a,&b,&c); Point prt=Point(a,b,c); prt=P[1]*prt.x+P[2]*prt.y+P[3]*prt.z+P[0]; printf("%lf %lf %lf\n",prt.x,prt.y,prt.z); } return 0; }
相关文章推荐
- readonly 和 disable的区别
- Ubuntu 14.10 下CPU实时监控mpstat命令详解
- Oracle函数
- POJ2155:Matrix(二维树状数组,经典)
- Web验证码的使用
- JavaWeb系列之十四(DBUtil)
- java 保存数据到mysql出现???
- JS格式化 /Date(xxxxxx)/的日期类型
- c#WebBrowser进阶
- POJ 3709 K-Anonymous Sequence
- Length of string in bash
- CvScalar
- Unity3D研究院之Assetbundle的实战(六十三)
- 59 js validate 调试模式 tp版本和css样式
- Python学习之一【使用Eclipse编写Python】
- 怎么在Release下调试代码
- 百度地图iOS SDK v2.8.0 地图不显示 只显示表格解决办法
- Java +apache+wget下载例子
- Spring整合Quartz
- 织梦dedecms转joomla!,如何自动添加文章分类-category