题目大意:
一个空间直角坐标系内,对一个点有三种操作:
1.平移(x,y,z)⇒(x+a,y+b,z+c);
2.缩放(x,y,z)⇒(ax,by,cz);
3.绕一个向量(x,y,z)顺时针旋转α角(角度制
对空间内的m个点给出
分析:
我们用i→,j→,k→表示x,y,z轴上的单位向量,和一个记录平移的p→向量(根据二维的仿射变换可以知道平移是不影响缩放和旋转的
平移直接给p→平移即可;
缩放对p→,i→,j→,k→依次缩放;
旋转对p→,i→,j→,k→依次旋转;
对于每个点(x,y,z),操作后就是(xi→,yj→,zk→)+p→。
关键就是怎样旋转。
对于点p绕
分析:
#include <cstdio>
#include <cmath>
typedef double DB;
using namespace std;
const DB PI = acos(-1.0);
const DB eps = 1e-10;
struct pot
{
DB x, y, z;
pot(DB x = 0, DB y = 0, DB z = 0):x(x),y(y),z(z){}
void read() {scanf("%lf%lf%lf", &x, &y, &z);}
void print() {printf("%lf %lf %lf\n", x, y, z);}
void trans(DB tx, DB ty, DB tz) {x += tx, y += ty, z += tz;}
void scal(DB tx, DB ty, DB tz) {x *= tx, y *= ty, z *= tz;}
void rotate(const pot &a, DB alpha)
{
pot p = *this, tmp;
tmp = a*((a*p)/(a*a));
p = p-tmp;pot m = a^p;
if(m.len() < eps) return ;
m.adjust(p.len());
*this = p*cos(alpha)+m*sin(alpha)+tmp;
}
friend pot operator + (const pot &a, const pot &b) {return pot(a.x+b.x, a.y+b.y, a.z+b.z);}
friend pot operator - (const pot &a, const pot &b) {return pot(a.x-b.x, a.y-b.y, a.z-b.z);}
friend pot operator * (const pot &a, DB k) {return pot(a.x*k, a.y*k, a.z*k);}
friend pot operator / (const pot &a, DB k) {return pot(a.x/k, a.y/k, a.z/k);}
friend DB operator * (const pot &a, const pot &b) {return a.x*b.x+a.y*b.y+a.z*b.z;}
friend pot operator ^ (const pot &a, const pot &b) {return pot(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);}
DB len() {return sqrt((*this)*(*this));}
void adjust(DB l) {*this = *this*(l/len());}
}p[4], v;
int main()
{
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
int n, m;
scanf("%d", &n);
p[1].x = p[2].y = p[3].z = 1;
while(n--)
{
DB x, y, z, a;
char q[3] = "\0";
scanf("%s", q);
scanf("%lf%lf%lf", &x, &y, &z);
if(q[0] == 'T') p[0].trans(x, y, z);
else if(q[0] == 'S')
for(int i = 0; i < 4; ++i)
p[i].scal(x, y, z);
else
{
scanf("%lf", &a);a *= PI/180;
for(int i = 0; i < 4; ++i)
p[i].rotate(pot(x, y, z), a);
}
}
scanf("%d", &m);
while(m--)
{
v.read();
v = p[0]+p[1]*v.x+p[2]*v.y+p[3]*v.z;
v.print();
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return 0;
}