zoukankan      html  css  js  c++  java
  • hdu 3320 计算几何(三维图形几何变换)

    openGL

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 170    Accepted Submission(s): 77


    Problem Description
    Jiaoshou selected a course about “openGL” this semester. He was quite interested in modelview, which is a part of “openGL”. Just using three functions, it could make the model to move, rotate and largen or lessen. But he was puzzled with the theory of the modelview. He didn’t know a vertex after several transformations where it will be.

    Now, He tells you the position of the vertex and the transformations. Please help Jiaoshou find the position of the vertex after several transformations.
     
    Input
    The input will start with a line giving the number of test cases, T.
    Each case will always begin with “glBegin(GL_POINTS);”.Then the case will be followed by 5 kinds of function.
    1. glTranslatef(x,y,z);
      This function will translate the vertex(x’,y’,z’) to vertex(x+x’,y+y’,z+z’).
    2. glRotatef(angle,x,y,z);
      This function will turn angle radians counterclockwise around the axis (0,0,0)->(x,y,z).
    3. glScalef(x,y,z);
      This function wiil translate the vertex(x’,y’,z’) to vertex(x*x’,y*y’,z*z’).
    4. glVertex3f(x,y,z);
      This function will draw an initial vertex at the position(x,y,z). It will only appear once in one case just before “glEnd();”. In openGL, the transformation matrices are right multiplied by vertex matrix. So you should do the transformations in the reverse order. 
    5. glEnd();
      This function tells you the end of the case.
    In this problem angle,x,y,z are real numbers and range from -50.0 to 50.0. And the number of functions in each case will not exceed 100.
     
    Output
    For each case, please output the position of the vertex after several transformations x,y,z in one line rounded to 1 digits after the decimal point , separated with a single space. We guarantee that x,y,z are not very large.
     
    Sample Input
    1
    glBegin(GL_POINTS);
    glScalef(2.0,0.5,3.0);
    glTranslatef(0.0,1.0,0.0);
    glVertex3f(1.0,1.0,1.0);
    glEnd();
     
    Sample Output
    2.0 1.0 3.0
    Hint
    In this sample, we first let the vertex do “glTranslatef(x,y,z);” this function, then do “glScalef(x,y,z)”.
     
    Author
    Water Problem SecKill Expert
     
    Source
     

    题目大意:给一个点的坐标,对它进行多种变换(平移变化、比例变换、绕任意轴旋转变换),输出它的最终坐标。不过它给出各变换的操作顺序是反过来的。 

    解题思路:构造各变换的变化矩阵,用矩阵乘法乘起来就是最终坐标。不会构造变化矩阵的详情请看下面:

    三维几何变换

     

    1. 三位平移变换是使立体在空间平移一段距离,其形状和大小保持不变。变化矩阵为

                     

                  

    2. 三维局部比例变换,关于原点的比例变换的变换矩阵为

          

    3. 三维立体绕通过原点的任意轴旋转角的变换。

    设ON为过坐标原点的一根任意轴,它对坐标轴的前方向余弦分别为

                    

    中间过程就不多说了详情请看计算机图形学教程(第2版)P176-P184,它的变换矩阵为

     

          

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 int cnt;
     8 char operat[105][105];
     9 double ang,x,y,z,xx,yy,zz;
    10 
    11 struct Matrix
    12 {
    13     double m[4][4];
    14 };
    15 
    16 Matrix mult(Matrix a,Matrix b)//矩阵乘法
    17 {
    18     Matrix c;
    19     for(int i=0;i<4;i++)
    20     {
    21         for(int j=0;j<4;j++)
    22         {
    23             c.m[i][j]=0.0;
    24             for(int k=0;k<4;k++)
    25                 c.m[i][j]+=a.m[i][k]*b.m[k][j];
    26         }
    27     }
    28     return c;
    29 }
    30 
    31 Matrix Translate(int i)//平移变换
    32 {
    33     sscanf(operat[i],"glTranslatef(%lf,%lf,%lf);",&x,&y,&z);
    34     Matrix tmp={1,0,0,0,0,1,0,0,0,0,1,0,x,y,z,1};
    35     return tmp;
    36 }
    37 Matrix RatioTranslate(int i)//局部比例变换
    38 {
    39     sscanf(operat[i],"glScalef(%lf,%lf,%lf);",&x,&y,&z);
    40     Matrix tmp={x,0,0,0,0,y,0,0,0,0,z,0,0,0,0,1};
    41     return tmp;
    42 }
    43 
    44 Matrix RotateTranslate(int i)//绕通过原点的任意轴旋转变换
    45 {
    46     sscanf(operat[i],"glRotatef(%lf,%lf,%lf,%lf);",&ang,&x,&y,&z);
    47     double t=sqrt(x*x+y*y+z*z);
    48     double n1=x/t;//cos(a),a是与x轴的夹角
    49     double n2=y/t;//cos(b),b是与y轴的夹角
    50     double n3=z/t;//cos(c),c是与z轴的夹角
    51     double S=sin(ang),C=cos(ang);
    52     Matrix tmp={n1*n1+(1-n1*n1)*C,n1*n2*(1-C)+n3*S,n1*n3*(1-C)-n2*S,0,
    53     n1*n2*(1-C)-n3*S,n2*n2+(1-n2*n2)*C,n2*n3*(1-C)+n1*S,0,
    54     n1*n3*(1-C)+n2*S,n2*n3*(1-C)-n1*S,n3*n3+(1-n3*n3)*C,0,
    55     0,0,0,1};
    56     return tmp;
    57 }
    58 
    59 Matrix solve()
    60 {
    61     Matrix ret={1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
    62     sscanf(operat[cnt-2], "glVertex3f(%lf,%lf,%lf);",&xx,&yy,&zz);
    63     for(int i=cnt-3;i>0;i--)
    64     {
    65         if(operat[i][2]=='T') 
    66             ret=mult(ret,Translate(i));
    67         else if(operat[i][2]=='S')
    68             ret=mult(ret,RatioTranslate(i));
    69         else if(operat[i][2]=='R')
    70             ret=mult(ret,RotateTranslate(i));
    71     }
    72     return ret;
    73 }
    74 
    75 int main()
    76 {
    77     int t;
    78     scanf("%d",&t);
    79     getchar();
    80     while(t--)
    81     {
    82         cnt=0;
    83         while(1)
    84         {
    85             gets(operat[cnt++]);
    86             if(operat[cnt-1][2]=='E')
    87                 break;
    88         }
    89         Matrix ans=solve();
    90         printf("%.1lf %.1lf %.1lf
    ",xx*ans.m[0][0]+yy*ans.m[1][0]+zz*ans.m[2][0]+ans.m[3][0],
    91             xx*ans.m[0][1]+yy*ans.m[1][1]+zz*ans.m[2][1]+ans.m[3][1],
    92             xx*ans.m[0][2]+yy*ans.m[1][2]+zz*ans.m[2][2]+ans.m[3][2]);
    93     }
    94     return 0;
    95 }
  • 相关阅读:
    jmeter循环发送http请求
    判断字符串是否为日期格式
    正则表达式的部分替换 $1~$99
    js验证上传文件大小
    mongodb主从备份 和 手动主从切换
    openproject安装与使用
    软件项目开发常见错误
    使用selenium的WebDriver和ChromeDriver实现UI自动化
    shell ssh远程执行命令
    Flask入门
  • 原文地址:https://www.cnblogs.com/xiong-/p/3936168.html
Copyright © 2011-2022 走看看