zoukankan      html  css  js  c++  java
  • HDU 4087 三维上的平移缩放旋转矩阵变化

     题目大意:

    就是根据它给的程序的要求,不断平移,缩放,旋转三维的点,最后计算出点的位置

    这里主要是要列出三种转换方式的齐次矩阵描述

    平移
    translate tx ty tz
    1 0 0 0
    0 1 0 0
    0 0 1 0
    tx ty tz 1
    缩放
    scale a b c
    a  0  0  0
    0  b  0  0
    0  0  c  0
    0  0  0  1
    绕任意轴(过原点)旋转(注意要把轴向量归一化,否则点在旋转轴上时有问题)

    这里是以(x,y,z)向量指向我们人的方向逆时针旋转 d 的弧度
    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

    然后这里因为循环的问题,所以用矩阵快速幂加速

    而循环是可能出现嵌套的

    我没用递归,而是判断当前循环属于第几个矩阵下的计算,每次进入一个新的循环都会给当前新的循环设置一个编号,以便找到它的矩阵

    每次退出循环,都会将当前矩阵和循环外那个矩阵相乘即可

    最后输出+eps,防止 -0.0 , -0.0 , -0.0 的情况发生

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm>
      5 #include <iostream>
      6 using namespace std;
      7 #define N 1005
      8 #define eps 1e-6
      9 const double PI = acos(-1.0);
     10 char s[20];
     11 int rec[N];
     12 
     13 struct Matrix{
     14     double m[4][4];
     15     Matrix operator*(const Matrix &t) const {
     16         Matrix ans;
     17         for(int i=0 ; i<4 ; i++){
     18             for(int j=0 ; j<4 ; j++){
     19                 ans.m[i][j] = 0;
     20                 for(int k=0 ; k<4 ; k++){
     21                     ans.m[i][j]+=m[i][k]*t.m[k][j];
     22                 }
     23             }
     24         }
     25         return ans;
     26     }
     27     Matrix(){}
     28     Matrix(double p[][4])
     29     {
     30         for(int i=0 ; i<4 ; i++)
     31             for(int j=0 ; j<4 ; j++)
     32                 m[i][j] = p[i][j];
     33     }
     34     void init(){
     35         memset( m , 0 , sizeof(m));
     36         for(int i=0 ; i<4 ; i++) m[i][i] = 1;
     37     }
     38     void out(){
     39         for(int i=0 ; i<4 ; i++){
     40             for(int j=0 ; j<4 ; j++)
     41                 cout<<m[i][j]<<" ";
     42             cout<<endl;
     43         }
     44     }
     45 }mat[1005] , tmp;
     46 
     47 Matrix q_pow(Matrix a , int k)
     48 {
     49     Matrix ret;
     50     ret.init();
     51     while(k)
     52     {
     53         if(k&1) ret = ret*a;
     54         a = a*a;
     55         k>>=1;
     56     }
     57     return ret;
     58 }
     59 //当向量方向指向自己的时候逆时针旋转A的弧度 
     60 void Rotate(Matrix &p , double a , double b , double c , double A)
     61 {
     62     double len = sqrt(a*a+b*b+c*c);
     63     double x = a/len , y = b/len , z = c/len;
     64     double sine = sin(A) , cosine = cos(A);
     65     double m[][4] = {
     66         {cosine+(1-cosine)*x*x, x*y*(1-cosine)-z*sine, x*z*(1-cosine)+y*sine, 0},
     67         {y*x*(1-cosine)+z*sine, cosine+y*y*(1-cosine), y*z*(1-cosine)-x*sine, 0},
     68         {z*x*(1-cosine)-y*sine, z*y*(1-cosine)+x*sine, cosine+z*z*(1-cosine), 0},
     69         {0                    , 0                    , 0                    , 1}
     70     };
     71     p = Matrix(m);
     72 }
     73 
     74 void Trans(Matrix &p , double a , double b , double c)
     75 {
     76     p.init();
     77     p.m[3][0]=a , p.m[3][1]=b , p.m[3][2]=c;
     78 }
     79 
     80 void Scale(Matrix &p , double a , double b , double c)
     81 {
     82     p.init();
     83     p.m[0][0] = a , p.m[1][1] = b , p.m[2][2] = c;
     84 }
     85 
     86 int main()
     87 {
     88    // freopen("in.txt" , "r" , stdin);
     89     int n;
     90     double a,b,c,d;
     91 
     92     while(scanf("%d" , &n) , n){
     93         mat[0].init();
     94         int cnt = 0;//repeat次数
     95         while(scanf("%s" , s)){
     96             if(s[0]=='e' && cnt==0) break;
     97             if(s[0]=='e'){
     98               //  cout<<"id: "<<cnt<<": "<<endl;
     99               //  mat[cnt].out();
    100                 mat[cnt] = q_pow(mat[cnt] , rec[cnt]);
    101               //  cout<<"id: "<<cnt<<": "<<endl;
    102               //  mat[cnt].out();
    103                 mat[cnt-1] = mat[cnt-1]*mat[cnt];
    104              //   cout<<"id: "<<cnt<<": "<<endl;
    105               //  mat[cnt-1].out();
    106                 cnt--;
    107             }
    108             if(s[0]=='r' && s[1]=='e') {
    109                 scanf("%d" , &rec[++cnt]);
    110                 mat[cnt].init();
    111             }
    112             else if(s[0]=='t'){
    113                 scanf("%lf%lf%lf" , &a , &b , &c);
    114                 Trans(tmp , a , b , c);
    115              //   tmp.out();
    116                 mat[cnt] = mat[cnt]*tmp;
    117             }
    118             else if(s[0]=='s'){
    119                 scanf("%lf%lf%lf" , &a , &b , &c);
    120                 Scale(tmp , a , b , c);
    121                 mat[cnt] = mat[cnt]*tmp;
    122             }
    123             else if(s[0]=='r' && s[1]=='o'){
    124                 scanf("%lf%lf%lf%lf" , &a , &b , &c , &d);
    125                 Rotate(tmp , a , b , c , -d/180*PI);
    126                 mat[cnt] = mat[cnt]*tmp;
    127             }
    128         }
    129       //  mat[0].out();
    130         for(int i=0 ; i<n ; i++){
    131             double x , y , z , xx , yy , zz;
    132             scanf("%lf%lf%lf" , &x , &y , &z);
    133             xx = x*mat[0].m[0][0]+y*mat[0].m[1][0]+z*mat[0].m[2][0]+mat[0].m[3][0];
    134             yy = x*mat[0].m[0][1]+y*mat[0].m[1][1]+z*mat[0].m[2][1]+mat[0].m[3][1];
    135             zz = x*mat[0].m[0][2]+y*mat[0].m[1][2]+z*mat[0].m[2][2]+mat[0].m[3][2];
    136             printf("%.2f %.2f %.2f
    " , xx+eps , yy+eps , zz+eps);
    137         }
    138         puts("");
    139     }
    140     return 0;
    141 }
  • 相关阅读:
    用DECODE进行排序
    linux下批量替换文件内容
    Linux下chkconfig命令详解
    linux 命令参数列表过长以及find用法
    参数上使用自定义注解在aop中无法获取到该参数
    AOP
    AOP aspect XML 配置
    AOP前世与今生,aspect
    ETL工具之——kettle使用简介
    ETL工具之kittle使用案例整理
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4678085.html
Copyright © 2011-2022 走看看