题目:点的变换
资料:http://www.matrix67.com/blog/archives/276/
主要思路:
(附图来自Matrix67大神)
注意点:对于各种操作,转化成矩阵之后,开始我随便写的Wa了一次,后来才发现我忘了矩阵乘法的不可交换性,所以对于一次给定的操作O1,O2,...On,初始矩阵B,我们运算的顺序应该是ANS=On * ..(. *(O2 * (O1 * B))) 然后根据结合律,所有的操作合并得到O=(On*....O2*O1),所以对于一次输入的操作,记住一定是左乘,右乘你就跪了。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define PI acos(-1.0)
struct Matrix
{
double m[4][4];
}E,matrix[10010];
void init()
{
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
if(i==j)
E.m[i][j]=1.0;
else
E.m[i][j]=0.0;
}
}
Matrix init_translation(double _x,double _y)
{
Matrix ans=E;
ans.m[1][3]=_x;
ans.m[2][3]=_y;
return ans;
}
Matrix init_zoom(double l)
{
Matrix ans=E;
ans.m[1][1]=l;
ans.m[2][2]=l;
return ans;
}
Matrix init_up_down()
{
Matrix ans=E;
ans.m[2][2]=-1;
return ans;
}
Matrix init_left_right()
{
Matrix ans=E;
ans.m[1][1]=-1;
return ans;
}
Matrix Multi(Matrix A,Matrix B)
{
Matrix ans;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
ans.m[i][j]=0;
for(int k=1;k<=3;k++)
ans.m[i][j]+=A.m[i][k]*B.m[k][j];
}
return ans;
}
Matrix init_rotate(double r)
{
Matrix ans=E;
ans.m[1][1]=cos(r);
ans.m[1][2]=-sin(r);
ans.m[2][1]=sin(r);
ans.m[2][2]=cos(r);
return ans;
}
Matrix last(Matrix A,Matrix B)
{
Matrix ans;
for(int i=1;i<=3;i++)
for(int j=1;j<=1;j++)
{
ans.m[i][j]=0;
for(int k=1;k<=3;k++)
ans.m[i][j]+=A.m[i][k]*B.m[k][j];
}
return ans;
}
int main()
{
init();
int N,M;
scanf("%d%d",&N,&M);
for(int i=1;i<=N;i++)
{
scanf("%lf%lf",&matrix[i].m[1][1],&matrix[i].m[2][1]);
matrix[i].m[3][1]=1;
}
Matrix ans=E;
char str[5];
double x,y;
for(int i=1;i<=M;i++)
{
scanf("%s",&str);
if(str[0]=='X')
ans=Multi(init_up_down(),ans);
else if(str[0]=='Y')
ans=Multi(init_left_right(),ans);
else if(str[0]=='M')
{
scanf("%lf%lf",&x,&y);
Matrix tmp=init_translation(x,y);
ans=Multi(init_translation(x,y),ans);
}
else if(str[0]=='R')
{
scanf("%lf",&x);
x/=180;
x*=PI;
ans=Multi(init_rotate(x),ans);
}
else if(str[0]=='S')
{
scanf("%lf",&x);
ans=Multi(init_zoom(x),ans);
}
}
for(int i=1;i<=N;i++)
{
matrix[i]=last(ans,matrix[i]);
printf("%.1lf %.1lf\n",matrix[i].m[1][1],matrix[i].m[2][1]);
}
return 0;
}