您的位置:首页 > 其它

SGU 265 Wizards(三维空间一点绕向量旋转)

2013-02-02 00:07 549 查看
题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=265

题意:给出点,经过平移、伸缩、旋转。求最后位置。

思路:主要是点绕向量的旋转。首先,求出点P到向量Q的投影向量temp,P=P-temp得到P垂直Q,M=Q*P得到M垂直Q,此时PM面垂直向量Q。将M调整与P一样长。最后答案为P*cos(x)+M*sin(x)+temp。

class Point
{
public:
double x,y,z;

Point()
{
x=y=z=0;
}
Point(double _x,double _y,double _z)
{
x=_x;
y=_y;
z=_z;
}

void read()
{
RD(x,y,z);
}

Point operator*(Point a)
{
return Point(y*a.z-a.y*z,z*a.x-a.z*x,x*a.y-a.x*y);
}

Point operator*(double t)
{
return Point(x*t,y*t,z*t);
}

double operator^(Point a)
{
return x*a.x+y*a.y+z*a.z;
}

Point operator+(Point a)
{
return Point(x+a.x,y+a.y,z+a.z);
}

Point operator-(Point a)
{
return Point(x-a.x,y-a.y,z-a.z);
}

Point scaling(double a,double b,double c)
{
return Point(x*a,y*b,z*c);
}

double getLen()
{
return sqrt(x*x+y*y+z*z);
}

Point adjust(double L)
{
double t=getLen();
L/=t;
return Point(x*L,y*L,z*L);
}

Point rotation(Point Q,double x)
{
Point p=*this,temp,m;
temp=Q*((p^Q)/(Q^Q));
p=p-temp;
m=Q*p;
if(m.getLen()<1e-10) return *this;
m=m.adjust(p.getLen());
return p*cos(x)+m*sin(x)+temp;
}

void print()
{
if(fabs(x)<1e-10) x=0;
if(fabs(y)<1e-10) y=0;
if(fabs(z)<1e-10) z=0;
printf("%lf %lf %lf\n",x,y,z);
}

};

int n,m;
Point p[4];

int main()
{
RD(n);
p[1].x=p[2].y=p[3].z=1;
char op[10];
double x,y,z,a;
int i,j;
FOR0(i,n)
{
RD(op);
if(op[0]=='T')
{
RD(x,y,z);
p[0]=p[0]+Point(x,y,z);
}
else if(op[0]=='S')
{
RD(x,y,z);
FOR0(j,4) p[j]=p[j].scaling(x,y,z);
}
else
{
RD(x,y,z);
RD(a);
a=a/180*PI;
FOR0(j,4) p[j]=p[j].rotation(Point(x,y,z),a);
}
}
RD(m);
Point temp;
while(m--)
{
temp.read();
temp=p[1]*temp.x+p[2]*temp.y+p[3]*temp.z+p[0];
temp.print();
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: