• [hdu][4087][ALetter to Programmers]


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4087

    三维旋转矩阵 + 矩阵加速

    这个还要用到仿射变换。

    平移

    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

     代码:

    View Code
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    
    #define forn(i,n) for(int i=0; i<(int)(n); i++)
    using namespace std;
    
    const int N = 4;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    
    struct matrix {
        int n;
        double a[N][N];
        void clear() {forn(i,n)forn(j,n)a[i][j]=0;}
        matrix(){}
        matrix(int z):n(z){clear();}
        matrix operator * (const matrix& u){
            matrix ans(n);
            forn(i,n) forn(k,n) forn(j,n)
                ans.a[i][j] += a[i][k] * u.a[k][j];
            return ans;
        }
        matrix pow(int k){
            matrix r(n), t=*this;
            forn(i,n) r.a[i][i]=1.0;
            while (k){
                if (k&1) r = t*r;
                t = t*t;
                k >>= 1;
            } return r;
        }
    };
    char op[20];
    
    matrix dfs(int tim){
        matrix res(4);
        forn(i,4)res.a[i][i]=1;
        double r[5];
        while (~scanf("%s", op)){
            if (op[0] == 'e') break;        // end
            matrix tmp(4);
            forn(i,4)tmp.a[i][i]=1;
            if (op[0] == 't'){                    // translate
                forn(i,3) scanf("%lf", &r[i]);
                forn(i,3) tmp.a[i][3]=r[i];
            }
            else if (op[0] == 's'){              // scale
                forn(i,3) scanf("%lf", &r[i]);
                forn(i,3) tmp.a[i][i]=r[i];
            }
            else if (op[0] == 'r' && op[1] == 'o'){     //rotate
                double t=0.0, c, s;
                forn(i,4) scanf("%lf", &r[i]);
                forn(i,3) t += r[i]*r[i];
                t = sqrt(t);
                forn(i,3) r[i] /= t;
                r[3] = r[3]/180*pi;
                c = cos(r[3]), s = sin(r[3]);
                forn(i,3){
                    forn(j,3){
                        bool f = (i+1)%3==j;
                        if (i == j) tmp.a[i][j]=(1-c)*r[i]*r[j]+c;
                        else tmp.a[i][j]=(1-c)*r[i]*r[j]+s*(f?-r[3^i^j]:r[3^i^j]);
                    }
                }
            }
            else {              // repeat
                int tim2;
                scanf("%d", &tim2);
                tmp = dfs(tim2);
            }
            res = tmp*res;
        }
        return res.pow(tim);
    }
    double p[5], q[5];
    int main()
    {
        //freopen("D:/a.txt", "r", stdin);
        int n;
        while (~scanf("%d", &n) && n){
            matrix tmp(4);
            forn(i,4)tmp.a[i][i]=1;
            tmp = dfs(1)*tmp;
            forn(i,n){
                forn(j,3) scanf("%lf",&p[j]);
                p[3] = 1.0;
                forn(j,3){
                    q[j] = 0.0;
                    forn(k,4) q[j]+=tmp.a[j][k]*p[k];
                }
                forn(j,3) printf("%.2f%c",q[j]+eps,j==2?'\n':' ');
            }
            puts("");
        }
        return 0;
    }

     

  • 相关阅读:
    开始熟悉一下数据结构了
    首个概率dp
    十六进制转化为八进制
    蓝桥之 剪格子
    蓝桥之 颠倒的价格
    还是闲的
    也是闲的
    闲的无聊,,,
    函数进阶
    函数基础
  • 原文地址:https://www.cnblogs.com/nigel0913/p/2603880.html
Copyright © 2020-2023  润新知