HDU 4998 Rotate (计算几何)

HDU 4998 Rotate (计算几何)

题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4998

Description

Noting is more interesting than rotation!
Your little sister likes to rotate things. To put it easier to analyze, your sister makes n rotations. In the i-th time, she makes everything in the plane rotate counter-clockwisely around a point ai by a radian of pi.
Now she promises that the total effect of her rotations is a single rotation around a point A by radian P (this means the sum of pi is not a multiplier of 2π).
Of course, you should be able to figure out what is A and P :).

Input

The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains an integer n denoting the number of the rotations. Then n lines follows, each containing 3 real numbers x, y and p, which means rotating around point (x, y) counter-clockwisely by a radian of p.
We promise that the sum of all p's is differed at least 0.1 from the nearest multiplier of 2π.
T<=100. 1<=n<=10. 0<=x, y<=100. 0<=p<=2π.

Output

For each test case, print 3 real numbers x, y, p, indicating that the overall rotation is around (x, y) counter-clockwisely by a radian of p. Note that you should print p where 0<=p<2π.
Your answer will be considered correct if and only if for x, y and p, the absolute error is no larger than 1e-5.

Sample Input

1
3
0 0 1
1 1 1
2 2 1

Sample Output

1.8088715944 0.1911284056 3.0000000000

题意:

平面内一个图形,给你n次旋转。每次围绕(x,y)逆时针旋转p度。问最终这个图形可以转换成围绕某点逆时针旋转多少度。

题解:

任意假设两个不同的点,依次模拟旋转n次后的点的位置。分别连接两点的旋转前和旋转后。作中垂线。交点就是我们要求的围绕旋转点。再通过余弦定理求角度。注意可能大于半园。需要最后将p代入判断是否满足。不满足则是2π-p。

代码:

#include <bits/stdc++.h>
using namespace std;
struct Point {
    double x,y ;
} ;
struct Rotate {
    double x,y,p ;
} ;
Rotate r[20] ;
int n ;
Point zhuan(Point a,Rotate b) {
    double co,si ;
    co = cos(b.p) ; si = sin(b.p) ;
    Point ans;
    ans.x = (a.x-b.x)*co - (a.y-b.y)*si + b.x ;
    ans.y = (a.y-b.y)*co + (a.x-b.x)*si + b.y ;
    return ans;
} 
double dis(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)) ;
}
const double eps = 1e-8 ;
double getp(Point d,Point x1,Point x2){
    double d1 = dis(d,x1) ;
    double d2 = dis(x1,x2) ;
    return acos((2*d1*d1-d2*d2)/(2*d1*d1)) ;
}
int main()
{
    int t;
    scanf("%d",&t) ;
    while (t--){
        scanf("%d",&n) ;
        Point x1,x2,x3,x4 ;
        x1 = {0,1} ;
        x2 = {1,0} ;
        x3 = x1 ;
        x4 = x2 ;
        for (int i = 1; i <= n; i++){
            scanf("%lf %lf %lf",&r[i].x,&r[i].y,&r[i].p) ;
            x3 = zhuan(x3,r[i]) ;
            x4 = zhuan(x4,r[i]) ;
        }
        double ax,ay,p ;
        if ((fabs(x1.x-x3.x) < eps)&&(fabs(x1.y-x3.y) < eps)){
            ax = x1.x ; ay = x1.y ; p = getp(x1,x2,x4) ;
        }else if ((fabs(x2.x-x4.x) < eps)&&(fabs(x2.y-x4.y) < eps)) {
            ax = x2.x ; ay = x2.y ; p = getp(x2,x1,x3) ;
        }else {
            double k1,k2,b1,b2 ;
            k1 = -(x1.x-x3.x)/(x1.y-x3.y) ;
            k2 = -(x2.x-x4.x)/(x2.y-x4.y) ;
            b1 = ((x1.x*x1.x-x3.x*x3.x) + (x1.y*x1.y-x3.y*x3.y))/(2.0*(x1.y-x3.y)) ;
            b2 = ((x2.x*x2.x-x4.x*x4.x) + (x2.y*x2.y-x4.y*x4.y))/(2.0*(x2.y-x4.y)) ;
            ax = (b2-b1)/(k1-k2) ;
            ay = k1*ax + b1 ;
            Point te={ax,ay} ;
            p = getp(te,x1,x3) ;
        }
        Rotate fuck = {ax,ay,p} ;
        Point ansfuck = zhuan(x1,fuck) ;
        if (!((fabs(x3.x-ansfuck.x)<eps)&&(fabs(x3.y-ansfuck.y)<eps)))
            p = 2.0*acos(-1.0)-p ;
        printf("%.7lf %.7lf %.7lf\n",ax,ay,p) ;
    }
    return 0 ;
}
posted @ 2016-09-08 22:56 Thecoollight 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/thecoollight/p/5854824.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值