矩阵乘法经典应用之坐标变化
2016-02-08 16:24
423 查看
二维空间:
问题:
nyist 298 点的变换
http://acm.nyist.net/JudgeOnline/problem.php?pid=298
大意:给出n个,对其进行m个操作,平移,旋转,缩放,翻转。其中n<=1e4 m<=1e6
分析:对于旋转:
x'=rcos(p+r)=xcosp-ysinp
y'=rsin (p+r)=xsinp+ycosp
然后是超时问题。想过用一个“基向量”先进行变换操作,然后再给每一个坐标进行变化,但是这样的“基向量”表示不了旋转变化操作。设想“基向量”是(1,1),各种问题出现了。。
矩阵是个好东西。它完全可以替代那个二维的“基向量”,实现操作压缩,后变化坐标。一个O(n*m)的算法程序变成了O(n+m)
旋转:
平移:
缩放:
绕X:
绕Y:
奇怪的答案:
double a=0.0;
printf("%.1lf\n",a+0.05);
--> 0.1
三维空间:
立体几何中的坐标变化:
平移:
缩放:
绕X轴旋转:
绕Y轴旋转:
绕Z轴旋转:
问题:
nyist 298 点的变换
http://acm.nyist.net/JudgeOnline/problem.php?pid=298
大意:给出n个,对其进行m个操作,平移,旋转,缩放,翻转。其中n<=1e4 m<=1e6
分析:对于旋转:
x'=rcos(p+r)=xcosp-ysinp
y'=rsin (p+r)=xsinp+ycosp
然后是超时问题。想过用一个“基向量”先进行变换操作,然后再给每一个坐标进行变化,但是这样的“基向量”表示不了旋转变化操作。设想“基向量”是(1,1),各种问题出现了。。
矩阵是个好东西。它完全可以替代那个二维的“基向量”,实现操作压缩,后变化坐标。一个O(n*m)的算法程序变成了O(n+m)
旋转:
平移:
缩放:
绕X:
绕Y:
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const int N=1e4+10; const double eps=1e-7, PI=acos(-1.0); struct point { double x,y; }pt ; struct matrix{ double m[3][3]; matrix(){ // 不写的话随机数字 for(int i=0;i<3;i++) for(int j=0;j<3;j++) m[i][j]=0; } }; matrix multi(matrix a,matrix b){ matrix ans; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ ans.m[i][j]=0; for(int k=0;k<3;k++){ ans.m[i][j]+=a.m[i][k]*b.m[k][j]; } } } return ans; } int main() { //freopen("cin.txt","r",stdin); int n,m; while(cin>>n>>m){ for(int i=0;i<n;i++){ scanf("%lf%lf",&pt[i].x,&pt[i].y); } matrix A; for(int i=0;i<3;i++){ A.m[i][i]=1; } char str[5]; for(int i=0;i<m;i++){ scanf("%s",str); matrix B; for(int i=0;i<3;i++) B.m[i][i]=1; if(str[0]=='M'){ double xx,yy; scanf("%lf%lf",&xx,&yy); B.m[0][2]=xx; B.m[1][2]=yy; } else if(str[0]=='X'){ B.m[1][1]=-1; } else if(str[0]=='Y'){ B.m[0][0]=-1; } else if(str[0]=='S'){ double p; scanf("%lf",&p); B.m[0][0]=p; B.m[1][1]=p; } else if(str[0]=='R'){ double al; scanf("%lf",&al); al=al/180*PI; B.m[0][0]=cos(al); B.m[0][1]=-sin(al); B.m[1][0]=sin(al); B.m[1][1]=cos(al); } A=multi(B,A); //multi(A,B); 左边是转换矩阵 右边是待转化答案 } for(int i=0;i<n;i++){ double px=A.m[0][0]*pt[i].x+A.m[0][1]*pt[i].y+A.m[0][2]; double py=A.m[1][0]*pt[i].x+A.m[1][1]*pt[i].y+A.m[1][2]; printf("%.1lf %.1lf\n",px,py); // +0.05 错了? } } return 0; }
奇怪的答案:
double a=0.0;
printf("%.1lf\n",a+0.05);
--> 0.1
三维空间:
立体几何中的坐标变化:
平移:
缩放:
绕X轴旋转:
绕Y轴旋转:
绕Z轴旋转:
相关文章推荐
- volley中多级别取消请求Request
- 中科院ICTCLA授权文件更新网址
- 注解和反射
- IT痴汉的工作现状44-外包困局
- 标准C++中的string类的用法总结
- nyoj 1112
- 1013. 数素数
- 数值的整数次方
- 安装交叉工具链
- ADO.NET之利用存储过程录入数据
- SSH 是什么
- Android算命小程序的实现
- 【翻译自mos文章】对于一个新建的db来说,对Dba_Feature_Usage_Statistics的查询返回零行
- python map、filter、reduce
- java 变长參数使用原则
- JavaScript 实现页面元素(ul-li)的简单排序
- CakePHP3.1中文手册
- DisplayMetircs 类
- [置顶] 利用django和python构建网络运维平
- JAVA设计模式实战---代理模式!!!