HDU4998 Rotate(旋转,线段相交模板)

Rotate

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=4998

题目意思:

平面上有一个二维坐标轴上,进行n次操作,把坐标轴绕着(x,y) (这个坐标总是初始坐标轴的坐标) 逆时针转p弧度。最后的结果相当于进行一次操作,即绕着(X, Y) 逆时针旋转了P弧度。求 X,Y,P,题目保证总有解.

解题思路:

不难发现,最后的P是n次的p的和,因为这和绕什么点旋转无关。(在草稿纸上画一个图理解一下吧)

至于求最后C点的坐标,那就简单了。

此题相当于是一个模板题,模板:http://blog.csdn.net/piaocoder/article/details/39255451

对任意点x1,x2,绕一个坐标点v逆时针旋转p角度后的新的坐标设为t1,t2,x1=t1,x2=t2;

循环上述操作,得到最后的 x1,x2;令x3等于最开始的x1,x4等于最开始的x2;最后点C的坐标,即为直线x1x3的垂直平分线与直线x2x4的垂直平分线的交点。

AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;

模板函数
struct Point{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
};

typedef Point Vector;

const double pi=4*atan(1.0);

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);
}

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 Cross(Vector A,Vector B){
    return A.x*B.y-A.y*B.x;
}

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(Point P,Vector v,Point Q,Vector w){
    Vector u = P-Q;
    double t = Cross(w,u)/Cross(v,w);
    return P+v*t;
}



int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n,t;
        Point v,t1,t2,t3,t4;
        Vector a,b,tmp1,tmp2;
        double p;
        double x,y,p1=0;
        t1.x=t1.y=t3.x=t3.y=0,t2.x=t2.y=t4.x=t4.y=1;
        Point a1,a2,c;
        scanf("%d",&n);
        for(int i = 0; i < n; i++){
            scanf("%lf%lf%lf",&v.x,&v.y,&p);
            tmp1 = t1-v;
            tmp2 = t2-v;
            t1 = Rotate(tmp1,p)+v;
            t2 = Rotate(tmp2,p)+v;
            //printf("%.10lf %.10lf \n",t1.x,t1.y);
            p1 += p;
        }
        t = p1/(2*pi);
        p1 -= t*(2*pi);
        a1 = (t1+t3)/2;a2=(t2+t4)/2;
        a = t1-t3;b=t2-t4;
        a = Normal(a);b = Normal(b);
        c = getlineintersection(a1,a,a2,b);
        printf("%.10lf %.10lf %.10lf\n",c.x,c.y,p1);
    }
    return 0;
}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值