sgu-265. Wizards

来源:互联网 发布:ddc控制器编程 编辑:程序博客网 时间:2024/06/03 19:34

题目大意:

空间直角坐标系中有M(M<=100000)个点,然后有一个操作集合,集合大小为N(N<=1000),操作包括平移,关于原点放缩,还有绕向量旋转。要你求出所有点操作完后的坐标。
 
 
 

解题思路:

显然这需要把N个操作都变为一个矩阵或者什么别的东西,使得最后计算答案的时候只需要进行一次操作就行了。
具体的操作方法再次不赘述了,主要是点绕向量旋转是一个问题。
这里写图片描述
我们令向量为t,点为p,因为题目保证t是以原点为起点,然后我们只要求出p对于t的垂直向量P然后叉乘得出垂直向量g,然后将g调整成和t长度相同,然后最后的到得点pgsin(α)+Pcos(α)+tmp

AC代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>using namespace std;const double PI=acos(-1);struct Point{    double x,y,z;    Point(){x=y=z=0;};    Point(double x_,double y_,double z_)    {x=x_,y=y_,z=z_;}    double operator^(Point a1)    {return x*a1.x+y*a1.y+z*a1.z;}    Point operator-(Point a1)    {return Point(x-a1.x,y-a1.y,z-a1.z);}    Point operator+(Point a1)    {return Point(x+a1.x,y+a1.y,z+a1.z);}    Point operator*(Point a1)    {return Point(y*a1.z-a1.y*z,z*a1.x-a1.z*x,x*a1.y-a1.x*y);}    Point operator*(double a1)    {return Point(x*a1,y*a1,z*a1);}    void scanling(double a,double b,double c)    {x*=a,y*=b,z*=c;}    double Lenth()    {return sqrt(x*x+y*y+z*z);}    void rotate(Point a1,double X)    {        Point cnt=Point(x,y,z);        Point tmp=a1*((cnt^a1)/(a1^a1));        cnt=cnt-tmp;        Point M=a1*cnt;        if(M.Lenth()<=1e-10) return;        M=M*(cnt.Lenth()/M.Lenth());        x=cnt.x*cos(X)+M.x*sin(X)+tmp.x;        y=cnt.y*cos(X)+M.y*sin(X)+tmp.y;        z=cnt.z*cos(X)+M.z*sin(X)+tmp.z;    }};void Readch(char &ch){    for(ch=getchar();ch=='\n' || ch=='\r' || ch==' ';ch=getchar());    return;}int main(){    char ch='\0';    int N;    scanf("%d",&N);    struct Point P[4];    P[1]=Point(1,0,0);P[2]=Point(0,1,0),P[3]=Point(0,0,1);    for(int i=1;i<=N;i++)    {        Readch(ch);        if(ch=='T')        {            double a,b,c;            scanf("%lf%lf%lf",&a,&b,&c);            P[0]=P[0]+Point(a,b,c);        }        else if(ch=='S')        {            double a,b,c;            scanf("%lf%lf%lf",&a,&b,&c);            for(int i=0;i<=3;i++) P[i].scanling(a,b,c);        }        else if(ch=='R')        {            double a,b,c,d;            scanf("%lf%lf%lf%lf",&a,&b,&c,&d);            d=d/180*PI;            for(int j=0;j<=3;j++)                P[j].rotate(Point(a,b,c),d);        }    }    int M;    scanf("%d",&M);    for(int i=1;i<=M;i++)    {        double a,b,c;        scanf("%lf%lf%lf",&a,&b,&c);        Point prt=Point(a,b,c);        prt=P[1]*prt.x+P[2]*prt.y+P[3]*prt.z+P[0];        printf("%lf %lf %lf\n",prt.x,prt.y,prt.z);    }    return 0;}
0 0
原创粉丝点击