,d);
}
}
return p;
}
int main()
{
int t;
double x,y,z;
scanf("%d",&t);
while(t--)
{
cnt=0;
while(1)
{
scanf("%s",opstr[cnt++]);
if (opstr[cnt-1][2]=='E')
break;
}
Matrix ans=work();
sscanf(opstr[cnt-2], "glVertex3f(%lf,%lf,%lf);",&x,&y,&z);
printf("%.1lf %.1lf %.1lf\n",x*ans.mat[1][1]+y*ans.mat[1][2]+z*ans.mat[1][3]+ans.mat[1][4],
x*ans.mat[2][1]+y*ans.mat[2][2]+z*ans.mat[2][3]+ans.mat[2][4],
x*ans.mat[3][1]+y*ans.mat[3][2]+z*ans.mat[3][3]+ans.mat[3][4]);
}
return 0;
}
弄明白了本例,可以顺手将HDU 4087 “ALetter to Programmers”做一下,以加深对三维几何变换的理解。HDU 4087比本例复杂一些,因为存在某个指定的平移、缩放或旋转操作集重复执行,因此会用到矩阵快速幂运算。
下面给出HDU 4087的源程序供参考。需要说明的是,这个源程序在HDU上用C++提交,一直Wrong Answer。采用G++提交可以Accepted。到现在我也没弄明白,所以仅供大家参考了。
(3)HDU 4087的参考源程序。
#include <stdio.h>
#include <math.h>
#include <string.h>
#define eps 1e-6
#define pi acos(-1.0)
struct Matrix { double mat[5][5]; // 存储矩阵中各元素
};
Matrix matMul(Matrix a ,Matrix b,int n) {
Matrix c;
memset(c.mat,0,sizeof(c.mat)); int i,j,k; for (k = 1; k<=n ; k++) for (i=1 ;i<=n ; i++) if (a.mat[i][k]!=0) for (j = 1 ;j<=n ;j++)
c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]); return c; }
Matrix quickMatPow(Matrix a ,int n,int b) // n阶矩阵a快速b次幂
{
Matrix c;
memset(c.mat ,0 ,sizeof(c.mat)); int i; for (i = 1 ;i <= n ;i++)
c.mat[i][i] = 1; while (b!=0) { if (b & 1)
c = matMul(c ,a ,n); // c=c*a;
a = matMul(a ,a ,n); // a=a*a
b /= 2; } return c; }
Matrix translate(Matrix p, double x, double y, double z) // 平移
{
Matrix tmp;
memset(tmp.mat,0,sizeof(tmp.mat)); for (int i=1;i<=4;i++)
tmp.mat[i][i]=1;
tmp.mat[1][4] = x;
tmp.mat[2][4] = y;
tmp.mat[3][4] = z;
p=matMul(tmp,p,4); return p; }
Matrix scale(Matrix p, double a, double b, double c) //缩放
{
Matrix tmp;
memset(tmp.mat,0,sizeof(tmp.mat)); for (int i=1;i<=4;i++)
tmp.mat[i][i]=1;
tmp.mat[1][1] = a;
tmp.mat[2][2] = b;
tmp.mat[3][3] = c;
p=matMul(tmp,p,4); return p; }
Matrix rotate(Matrix p, double x, double y, double z, double d) // 旋转
{
d = d/180*pi; double di = sqrt(x*x+y*y+z*z); //单位化
x/=di, y/=di, z/=di;
Matrix tmp;
memset(tmp.mat,0,sizeof(tmp.mat));
tmp.mat[1][1] = (1-cos(d))*x*x + cos(d);
tmp.mat[1][2] = (1-cos(d))*x*y - z*sin(d);
tmp.mat[1][3] = (1-cos(d))*x*z + y*sin(d);
tmp.mat[2][1] = (1-cos(d))*x*y + z*sin(d);
tmp.mat[2][