hdu4087ALetter to Programmers(三维旋转矩阵)

参考

三维旋转矩阵 + 矩阵加速

这个还要用到仿射变换。

平移

translate tx ty tz

1 0 0 tx

0 1 0 ty

0 0 1 tz

0 0 0 1

缩放

scale kx ky kz

kx 0  0  0

0  ky 0  0

0  0  kz 0

0  0  0  1

绕任意轴(过原点)旋转(注意要把轴向量归一化,不然会在“点在轴上”这个情况下出问题)

rotate x y z d

(1-cos(d))*x*x+cos(d)     (1-cos(d))*x*y-sin(d)*z   (1-cos(d))*x*z+sin(d)*y   0

(1-cos(d))*y*x+sin(d)*z   (1-cos(d))*y*y+cos(d)     (1-cos(d))*y*z-sin(d)*x   0

(1-cos(d))*z*x-sin(d)*y   (1-cos(d))*z*y+sin(d)*x   (1-cos(d))*z*z+cos(d)     0

0                                     0                                      0                       1

类似于一种构造矩阵的方式,每一种操作都相当于乘一次矩阵,具体第三个怎么推出来的没看懂。。。

矩阵乘法不支持交换律,一定要看好顺序。。debug了一天。。

据说会有-0.00这种答案不通过的坑,不过下面的代码加了eps..

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 1010
 12 #define LL long long
 13 #define INF 0xfffffff
 14 #define forn(i,n) for(int i=0; i<(int)(n); i++)
 15 const double eps = 1e-6;
 16 const double pi = acos(-1.0);
 17 const double inf = ~0u>>2;
 18
 19 struct point3
 20 {
 21     double x,y,z;
 22 } p[N];
 23 struct Mat
 24 {
 25     double mat[5][5];
 26 };
 27 int n,m;
 28 char str[20];
 29 Mat operator * (Mat a,Mat b)
 30 {
 31     Mat c;
 32     memset(c.mat,0,sizeof(c.mat));
 33     int i,j,k;
 34     for(i = 0 ; i < n ; i++)
 35         for(j = 0 ; j < n ; j++)
 36             for(k =0 ; k < n ; k++)
 37                 c.mat[i][j] +=a.mat[i][k]*b.mat[k][j];
 38     return c;
 39 }
 40 Mat operator ^(Mat a,int k)
 41 {
 42     Mat c;
 43
 44     int i,j;
 45     for(i =0 ; i < n ; i++)
 46         for(j = 0; j < n ; j++)
 47             c.mat[i][j] = (i==j);
 48     for(; k ; k >>= 1)
 49     {
 50         if(k&1) c = c*a;
 51         a = a*a;
 52     }
 53     return c;
 54 }
 55 Mat solve(int k)
 56 {
 57
 58     Mat cc;
 59     double a[10];
 60     int i;
 61     memset(cc.mat,0,sizeof(cc.mat));
 62     for(i = 0 ; i < 4 ; i++) cc.mat[i][i] = 1;
 63     while(~scanf("%s",str))
 64     {
 65         if(str[0]==‘e‘)
 66         {
 67             break;
 68         }
 69         Mat c;
 70         memset(c.mat,0,sizeof(c.mat));
 71         for(i = 0 ; i < 4 ; i++) c.mat[i][i] = 1;
 72         if(str[0]==‘t‘)
 73         {
 74             forn(i,3) scanf("%lf", &a[i]);
 75             forn(i,3) c.mat[i][3]=a[i];
 76         }
 77         else if(str[0]==‘s‘)
 78         {
 79             for(i = 0 ; i < 3 ; i++)
 80                 scanf("%lf",&a[i]);
 81             for(i = 0 ; i < 3; i++)
 82                 c.mat[i][i] = a[i];
 83         }
 84         else if(str[0]==‘r‘&&str[1]==‘o‘)
 85         {
 86             for(i =0  ; i < 4; i++) scanf("%lf",&a[i]);
 87             a[3] = a[3]/180*pi;
 88             double mag=sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]);
 89             a[0]/=mag;
 90             a[1]/=mag;
 91             a[2]/=mag;
 92             c.mat[0][0] = (1-cos(a[3]))*a[0]*a[0]+cos(a[3]);
 93             c.mat[0][1] = (1-cos(a[3]))*a[0]*a[1]-sin(a[3])*a[2];
 94             c.mat[0][2] = (1-cos(a[3]))*a[0]*a[2]+sin(a[3])*a[1];
 95             c.mat[1][0] = (1-cos(a[3]))*a[0]*a[1]+sin(a[3])*a[2];
 96             c.mat[1][1] = (1-cos(a[3]))*a[1]*a[1]+cos(a[3]);
 97             c.mat[1][2] = (1-cos(a[3]))*a[1]*a[2]-sin(a[3])*a[0];
 98             c.mat[2][0] = (1-cos(a[3]))*a[0]*a[2]-sin(a[3])*a[1];
 99             c.mat[2][1] = (1-cos(a[3]))*a[1]*a[2]+sin(a[3])*a[0];
100             c.mat[2][2] = (1-cos(a[3]))*a[2]*a[2]+cos(a[3]);
101         }
102         else if(str[0]==‘r‘)
103         {
104             int kk ;
105             scanf("%d",&kk);
106             c = solve(kk);
107         }
108         cc = c*cc;
109     }
110     return cc^k;
111 }
112 int dcmp(double x)
113 {
114     if(fabs(x)<eps) return 0;
115     return x<0?-1:1;
116 }
117 int main()
118 {
119     int i,j;
120     n = 4;
121     while(scanf("%d",&m)&&m)
122     {
123         Mat c;
124         memset(c.mat,0,sizeof(c.mat));
125         for(i = 0; i < n; i++) c.mat[i][i] = 1;
126         c = solve(1)*c;
127         for(i = 1; i <= m; i++)
128         {
129             Mat x,y;
130             memset(y.mat,0,sizeof(y.mat));
131             for(j = 0 ; j < 3 ; j++)
132                 scanf("%lf",&y.mat[j][3]);
133             y.mat[3][3] = 1;
134             x = c*y;
135             p[i].x = x.mat[0][3],p[i].y = x.mat[1][3],p[i].z = x.mat[2][3];
136         }
137         for(i = 1; i <= m; i++)
138         {
139             printf("%.2f %.2f %.2f\n",p[i].x+eps,p[i].y+eps,p[i].z+eps);
140         }
141         puts("");
142     }
143     return 0;
144 }

时间: 2024-08-13 18:08:47

hdu4087ALetter to Programmers(三维旋转矩阵)的相关文章

【转】[专题学习][计算几何]

原文地址:http://www.cnblogs.com/ch3656468/archive/2011/03/02/1969303.html 基本的叉积.点积和凸包等东西就不多说什么了,网上一搜一大堆,切一些题目基本熟悉了就差不多了. 一些基本的题目可以自己搜索,比如这个blog:http://blog.sina.com.cn/s/blog_49c5866c0100f3om.html 接下来,研究了半平面交,思想方法看07年朱泽园的国家队论文,模板代码参考自我校大牛韬哥: http://www.o

深入理解图优化与g2o:图优化篇

前言 本节我们将深入介绍视觉slam中的主流优化方法——图优化(graph-based optimization).下一节中,介绍一下非常流行的图优化库:g2o. 关于g2o,我13年写过一个文档,然而随着自己理解的加深,越发感觉不满意.本着对读者更负责任的精神,本文给大家重新讲一遍图优化和g2o.除了这篇文档,读者还可以找到一篇关于图优化的博客: http://blog.csdn.net/heyijia0327 那篇文章有作者介绍的一个简单案例,而本文则更注重对图优化和g2o的理解与评注. 本

四轴飞行器1.1 Matlab 姿态显示

四轴飞行器1.1 Matlab 姿态显示 开始做四轴了,一步一步来,东西实在很多,比较杂.先做matlab上位机,主要用来做数据分析,等板子到了可以写飞控的程序了,从底层一层一层开始写..希望能好好的完成它...关于matlab上位机,首先做个姿态显示,然后等板子来了,把板子底层程序写好后,加上matlab的串口接收部分,基本的环境就算搭建好了.... 这个代码写了一天,写到最后出现戏剧性的一幕,实在是太恶心了哈..开始自己的想法就是通过输入pitch roll yaw三个欧拉角,然后在空间中现

iOS开发-OpenGLES 入门踩坑

Flat coloring(单色) 是通知OpenGL使用单一的颜色来渲染,OpenGL将一直使用指定的颜色来渲染直到你指定其它的颜色. 指定颜色的方法为 public abstract void glColor4f(float red, float green, float blue, float alpha). 缺省的red,green,blue为1,代表白色. Smooth coloring (平滑颜色过渡) 当给每个顶点定义一个颜色时,OpenGL自动为不同顶点颜色之间生成中间过渡颜色(

《线性代数》随笔:学以致用

朝花夕拾 勿忘初心 学以致用 青出于蓝 积沙成塔 线性代数就是把一组数通过线性组合得到另一组数.所谓的线性组合,就像买菜一样,我可以买半斤青菜.两根胡萝卜还有一棵西兰花――都是把每种菜乘上一个常数最后加起来算个总账.我绝不会说我要买青菜乘上萝卜.或者西兰花除以两斤青菜.菜和菜之间的乘除是毫无意义的.所以买菜就是一种线性组合. 我之前说到过,我是因为工作上写程序要用到才去重新学习了线性代数.这其中所涉及的问题其实大家在高中就经常做这类的题目,就是坐标变换.在数学家的眼里,所有的几何图形都是数字或公

关于自由移站法及坐标转换模型的综述

 更多资讯见xiaok海洋测绘网 1.自由移站法的核心是大旋转角坐标转换的平差算法 2.大旋转角坐标转换方法有三种:七参数法,罗德里格矩阵,简便算法 3.七参数法是一种 局部最优算法,它的好坏取决于初始值 4.罗德里格矩阵摆脱了七参数法的三角函数,在初始值相同的情况下,精度比七参数法略差 5.简便算法其实是13参数法,七参数法的一个变种,参考了罗德里格的思想,易于编程 潘国荣等<工业测量三维基准转换参数的全局最优算法>2014年 摘 要:从全局最优的角度分析了工业测量空间三维基准转换时经常

SLAM学习笔记 - 世界坐标系到相机坐标系的变换

参考自: http://blog.csdn.net/yangdashi888/article/details/51356385 http://blog.csdn.net/li_007/article/details/5976261 其中,Zc表示单目相机的尺度不确定性(单目相机无法确定尺度,所以ORB-SLAM等最后都对单目做了sim3优化) 等号右边第一.二个矩阵经常乘在一起作为相机内参,其中dx.dy是像面上每个像素点在x轴y轴上的尺寸,u0和v0用来把图像坐标原点从图像中心挪到左上角,f表

Three.js 学习笔记(1)--坐标体系和旋转

前言 JavaScript 3D library The aim of the project is to create an easy to use, lightweight, 3D library. The library provides <canvas>, <svg>, CSS3D and WebGL renderers.(该项目的目标是创建一个易于使用,轻量级的3D库.该库提供了<canvas>,<svg>,CSS3D和WebGL渲染器.) 示例 

《SLAM十四讲》个人学习知识点梳理

0.引言 从六月末到八月初大概一个月时间一直在啃SLAM十四讲[1]这本书,这本书把SLAM中涉及的基本知识点都涵盖了,所以在这里做一个复习,对这本书自己学到的东西做一个梳理. 书本地址:http://www.broadview.com.cn/book/4938 书本代码:https://github.com/gaoxiang12/slambook 1.SLAM概述 SLAM:即时定位与地图构建(Simultaneous Localization and Mapping) 数学描述: 一个典型的