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 }
View Code

 

posted @ 2014-09-08 17:09  _雨  阅读(306)  评论(0编辑  收藏  举报