zoukankan      html  css  js  c++  java
  • hdu4998 旋转坐标系

    题意:
          一开始的时候有一个坐标系(正常的),然后有n个操作,每个操作是 x y d,意思是当前坐标系围绕x,y点逆时针旋转d度,最后让你输出三个数x y d,把这n个操作的最后结果,用一步等效过来,就是找到一个点,逆时针旋转一个度数,等于当前的这个状态。

    思路:

          我们可以用一个向量来代表当前坐标系,每次操作把当前向量拆成两个点单独操作,假如当前向量a,b,绕点c旋转d度,那么我们可以等效向量c,a逆时针旋转d,然后向量c,b逆时针旋转d,这样就的到了两个新的向量,此时我们要根据这两个新的向量求出当前这两个点的新位置,然后再用当前的新位置和下一组操作,最后得到了最终的一个向量,现在我们只要求出初始向量和最终向量的转换关系就行了,这个地方首先我们求转换点,求法是两个向量的x,x'连线,y.y'连线,两条线段中垂线的交点,求出交点之后再用余弦定理求出夹角,然后在用向量的关系来判断要不要用2PI-当前度数,具体看代码。


    #include<math.h>
    #include<algorithm>
    #include<stdio.h>
    #define maxn 60
    #define eps 1e-7
    #define PP (3.141592653589793238)
    using namespace std;
    
    int dcmp(double x)    
    {
        if(fabs(x)<eps) return 0;
        else return x<0?-1:1;
    }
    double toRad(double deg)   
    {
        return deg/180.0*acos(-1.0);
    }
    struct Point
    {
        double x,y;
        Point(){}
        Point(double x,double y):x(x),y(y) {}
        void input()
        {
            scanf("%lf %lf",&x,&y);
        }
    };
    typedef Point Vector;
    
    Vector operator+( Vector A, Vector B )      
    {
        return Vector( A.x + B.x, A.y + B.y );
    }
    Vector operator-(Vector A,Vector B)      
    {
        return Vector( A.x - B.x, A.y - B.y );
    }
    Vector operator*( Vector A, double p )     
    {
        return Vector( A.x * p, A.y * p );
    }
    Vector operator/( Vector A, double p )      
    {
        return Vector( A.x / p, A.y / p );
    }
    bool operator<(const Point& A, const Point& B )   
    {
        return dcmp( A.x - B.x ) < 0 || ( dcmp( A.x - B.x ) == 0 && dcmp( A.y - B.y ) < 0 );
    }
    bool operator==( const Point& a, const Point& b )   
    {
        return dcmp( a.x - b.x ) == 0 && dcmp( a.y - b.y ) == 0;
    }
    struct Line
    {
        Point s,e;
        Vector v;
        Line() {}
        Line(Point s,Point v,int type):
            s(s),v(v){}
        Line(Point s,Point e):s(s),e(e)
        {v=e-s;}
    
    };
    double Dot(Vector A,Vector B)
    {
        return A.x*B.x+A.y*B.y;
    }
    double Length(Vector A)
    {
        return sqrt(Dot(A,A));
    }
    double Angle(Vector A,Vector B)
    {
        return acos(Dot(A,B)/Length(A)/Length(B));
    }
    double Cross(Vector A,Vector B)
    {
        return A.x*B.y-A.y*B.x;
    }
    double Area2(Point A,Point B,Point C )
    {
        return Cross(B-A,C-A);
    }
    double Dist(Point A,Point B)
    {
        return Length(A-B);
    }
    Vector Rotate(Vector A, double rad)
    {
        return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
    }
    Vector Normal(Vector A)
    {
        double L=Length(A);
        return Vector(-A.y/L,A.x/L);
    }
    Point GetLineIntersection(Line l1,Line l2)
    {
        Point P=l1.s;
        Vector v=l1.v;
        Point Q=l2.s;
        Vector w=l2.v;
        Vector u=P-Q;
        double t=Cross(w,u)/Cross(v,w);
        return P+v*t;
    }
    double DistanceToLine(Point P,Line L)
    {
        Point A,B;
        A=L.s,B=L.e;
        Vector v1=B-A,v2=P-A;
        return fabs(Cross(v1,v2))/Length(v1);
    }
    double DistanceToSegment(Point P, Line L)
    {
        Point A,B;
        A=L.s,B=L.e;
        if(A==B) return Length(P-A);
        Vector v1=B-A,v2=P-A,v3=P-B;
        if (dcmp(Dot(v1,v2))<0) return Length(v2);
        else if (dcmp(Dot(v1,v3))>0) return Length(v3);
        else return fabs(Cross(v1,v2)) / Length(v1);
    }
    Point GetLineProjection(Point P,Line L)
    {
        Point A,B;
        A=L.s,B=L.e;
        Vector v=B-A;
        return A+v*(Dot(v,P-A)/Dot(v,v));
    }
    
    double abss(double x)
    {
       return x < 0 ? -x : x;
    }
    
    
    bool OnSegment(Point p,Line l)
    {
        Point a1=l.s;
        Point a2=l.e;
        return dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dist(p,a1)+Dist(p,a2)-Dist(a1,a2))==0;
    }
    bool Paralled(Line l1,Line l2)
    {
        return dcmp(Cross(l1.e-l1.s,l2.e-l2.s))==0;
    }
    bool SegmentProperIntersection(Line l1,Line l2)
    {
        if(Paralled(l1,l2))
        {
            return false;
        }
        Point t=GetLineIntersection(l1,l2);
        if(OnSegment(t,l1))
        {
            return true;
        }
        return false;
    }
    
    int main ()
    {
       double x ,y ,p;
       int T ,n ,i;
       scanf("%d" ,&T);
       while(T--)
       {
          scanf("%d" ,&n);
          double nowx1  = 0 ,nowy1 = 0;
          double nowx2  = 0 ,nowy2 = 101.0;
          double sss = 0;;
          Vector A ,B;
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%lf %lf %lf" ,&x ,&y ,&p);
             if(p == 0.0 || abss(p - PP * 2) <= 0.00001) continue;
             sss += p;
             A.x = nowx1 - x ,A.y = nowy1 - y;
             B = Rotate(A ,p);
             nowx1 = x + B.x ,nowy1 = y + B.y;
             A.x = nowx2 - x ,A.y = nowy2 - y;
             B = Rotate(A ,p);
             nowx2 = x + B.x ,nowy2 = y + B.y;
          }
          if(nowx1 == 0.0 && nowy1 == 0.0)
          {
              double x4 = nowx2 ,y4 = nowy2;
              double x3 = 0 ,y3 = 0;
              double x1 = 0 ,y1 = 101.0;
              double aaa;
              double tmp = (x4 - x3) * (x1 - x3) + (y4 - y3) * (y1 - y3);
              tmp = tmp / (pow(x4 - x3 ,2.0) + pow(y4 - y3 ,2.0));
              aaa = acos(tmp);
              double q1 = 0 ,q2 = 0;
              if(nowx2 > 0.0) aaa = PP * 2 - aaa;  
              if(abss(aaa - PP * 2) <= 0.00001)aaa = 0;
              printf("%lf %lf %lf
    " ,q1 ,q2 ,aaa);
          }
          else if(nowx2 == 0.0 && nowy2 == 101.0)
          {
              double x4 = nowx1 ,y4 = nowy1;
              double x3 = 0 ,y3 = 101.0;
              double x1 = 0 ,y1 = 0;
              double aaa;
              double tmp = (x4 - x3) * (x1 - x3) + (y4 - y3) * (y1 - y3);
              tmp = tmp / (pow(x4 - x3 ,2.0) + pow(y4 - y3 ,2.0));
              aaa = acos(tmp);
              double q1 = 0 ,q2 = 101.0;
              if(nowx1 < 0) aaa = PP * 2 - aaa;
              if(abss(aaa - PP * 2) <= 0.00001)aaa = 0;
              printf("%lf %lf %lf
    " ,q1 ,q2 ,aaa);
          }
          else
          {   
             Point AA1;
             AA1.x = AA1.y = 0;
             Point BB1;
             BB1.x = nowx1 ,BB1.y = nowy1;    
             Line now1 = Line((AA1 + BB1)/2 ,Normal(AA1 - BB1),1);          
             Point AA2;
             AA2.x = 0 ,AA2.y = 101.0;
             Point BB2;
             BB2.x = nowx2 ,BB2.y = nowy2;
             Line now2 = Line((AA2 + BB2)/2 ,Normal(AA2 - BB2),1);     
             Point now = GetLineIntersection(now1 ,now2);
             double x4 = nowx1 ,y4 = nowy1;
             double x3 = now.x ,y3 = now.y;
             double x1 = 0 ,y1 = 0;
             double aaa;
             double tmp = (x4 - x3) * (x1 - x3) + (y4 - y3) * (y1 - y3);
             tmp = tmp / (pow(x4 - x3 ,2.0) + pow(y4 - y3 ,2.0));
             double x2 ,y2;
             x1 = 0 ,y1 = 101;
             x2 = nowx2 - nowx1 ,y2 = nowy2 - nowy1;
             aaa = acos(tmp);
             if(x1*y2-x2*y1<0) aaa = PP * 2 - aaa;
             printf("%lf %lf %lf
    " ,now.x ,now.y ,aaa);       
         }
       }
       return 0;
    }     
             
    

  • 相关阅读:
    轻重搭配
    EF的优缺点
    使用bootstrap-select有时显示“Nothing selected”
    IIS发布 HTTP 错误 500.21
    js添加的元素无法触发click事件
    sql server查看表是否死锁
    sql server把一个库表的某个字段更新到另一张表的相同字段
    SQLSERVER排查CPU占用高的情况
    SQL server中如何按照某一字段中的分割符将记录拆成多条
    LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.
  • 原文地址:https://www.cnblogs.com/csnd/p/12062784.html
Copyright © 2011-2022 走看看