题目大意:
一个空间直角坐标系内,对一个点有三种操作:
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;
}