HDU 4998 (点的旋转) Rotate

为了寻找等效旋转操作,我们任选两个点P0和Q0,分别绕这n个点旋转一定的角度后最终得到Pn和Qn

然后已知:P0和Pn共圆,Q0和Qn共圆。所以要找的等效旋转点就是这两个线段的垂直平分线交点O。

等效的角度的计算,可以利用已知的等腰三角形(这里有两个)△P0PnR,做一条垂线(三线合一的性质),再利用反三角函数计算半角,再乘二

还有一种特殊情况就是,如果答案比平角要大,我们计算的角度就不对了。

此时可以让P0逆时针旋转90°得到一个P1,然后将P1和Pn的坐标分别代入直线P0R的方程,如果异号,说明P1和Pn在直线两侧;同号说明同侧。

也就是异侧的话,就要将所求角度用2π减去它。

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cmath>
 6 using namespace std;
 7
 8 void Rote(double& a1, double& b1, double a2, double b2, double p)
 9 {
10     double tempx = a1, tempy = b1;
11     tempx = cos(p)*(a1 - a2) + sin(p)*(b2 - b1) + a2;
12     tempy = sin(p)*(a1 - a2) + cos(p)*(b1 - b2) + b2;
13     a1 = tempx;
14     b1 = tempy;
15 }
16
17 double dis(double a1, double b1, double a2, double b2)
18 {
19     return sqrt((a1-a2)*(a1-a2) + (b1-b2)*(b1-b2));
20 }
21
22 int main(void)
23 {
24     #ifdef LOCAL
25         freopen("Bin.txt", "r", stdin);
26     #endif
27
28     int T;
29     scanf("%d", &T);
30     while(T--)
31     {
32         int n;
33         scanf("%d", &n);
34         double P0x = 0.123, P0y = 0.312, Q0x = 1.589, Q0y = 1.455;
35         double Pnx = P0x, Pny = P0y, Qnx = Q0x, Qny = Q0y;
36         for(int i = 0; i < n; ++i)
37         {
38             double P1x, P1y, alpha;
39             scanf("%lf%lf%lf", &P1x, &P1y, &alpha);
40             Rote(Pnx, Pny, P1x, P1y, alpha);
41             Rote(Qnx, Qny, P1x, P1y, alpha);
42         }
43         double A1 = P0x - Pnx, B1 = P0y - Pny, C1 = (P0x*P0x + P0y*P0y - Pnx*Pnx - Pny*Pny) / 2;
44         double A2 = Q0x - Qnx, B2 = Q0y - Qny, C2 = (Q0x*Q0x + Q0y*Q0y - Qnx*Qnx - Qny*Qny) / 2;
45         double ansx = (C1*B2 - C2*B1) / (A1*B2 - A2*B1);
46         double ansy = (C1*A2 - C2*A1) / (B1*A2 - B2*A1);
47
48         double zx = (P0x + Pnx) / 2, zy = (P0y + Pny) / 2;
49         double ansa = acos(dis(zx,zy, ansx, ansy) / dis(P0x, P0y, ansx, ansy)) * 2;
50
51         double P1x = ansx - (P0y - ansy), P1y = ansy + (P0x - ansx);
52         if(((P0y-ansy)*(P1x-ansx)-(P0x-ansx)*(P1y-ansy)) * ((P0y-ansy)*(Pnx-ansx)-(P0x-ansx)*(Pny-ansy)) < 0)
53             ansa = 3.1415926536 * 2 - ansa;
54
55         printf("%.10lf %.10lf %.10lf\n", ansx, ansy, ansa);
56     }
57     return 0;
58 }

代码君

还有一种复数的方法,<complex>里面已经有了现成的复数数据类型和函数了,用起来很方便。

这是上交一队的代码,膜拜了

 1 #include <cstdlib>
 2 #include <cctype>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <string>
 9 #include <iostream>
10 #include <sstream>
11 #include <map>
12 #include <set>
13 #include <queue>
14 #include <stack>
15 #include <fstream>
16 #include <numeric>
17 #include <iomanip>
18 #include <bitset>
19 #include <list>
20 #include <stdexcept>
21 #include <functional>
22 #include <utility>
23 #include <ctime>
24 #include <cassert>
25 #include <complex>
26 using namespace std;
27 #define rep(i,a,n) for (int i=a;i<n;i++)
28 #define per(i,a,n) for (int i=n-1;i>=a;i--)
29 #define pb push_back
30 #define mp make_pair
31 #define all(x) (x).begin(),(x).end()
32 #define fi first
33 #define se second
34 #define SZ(x) ((int)(x).size())
35 #define ACCU accumulate
36 #define TWO(x) (1<<(x))
37 #define TWOL(x) (1ll<<(x))
38 #define clr(a) memset(a,0,sizeof(a))
39 #define POSIN(x,y) (0<=(x)&&(x)<n&&0<=(y)&&(y)<m)
40 #define PRINTC(x) cout<<"Case #"<<++__<<": "<<x<<endl
41 #define POP(x) (__builtin_popcount(x))
42 #define POPL(x) (__builtin_popcountll(x))
43 typedef vector<int> VI;
44 typedef vector<string> VS;
45 typedef vector<double> VD;
46 typedef long long ll;
47 typedef long double LD;
48 typedef pair<int,int> PII;
49 typedef pair<ll,ll> PLL;
50 typedef vector<ll> VL;
51 typedef vector<PII> VPII;
52 typedef complex<double> CD;
53 const int inf=0x20202020;
54 const ll mod=1000000007;
55 const double eps=1e-9;
56 const double pi=3.1415926535897932384626;
57 const int DX[]={1,0,-1,0},DY[]={0,1,0,-1};
58 ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
59 ll powmod(ll a,ll b,ll mod) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
60 ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
61 // head
62
63 int _,n;
64 CD k,b,p;
65 double x,y,c;
66 int main() {
67     for (scanf("%d",&_);_;_--) {
68         k=CD(1,0);b=CD(0,0);
69         scanf("%d",&n);
70         rep(i,0,n) {
71             scanf("%lf%lf%lf",&x,&y,&c);
72             p=CD(x,y);
73             k=k*CD(cos(c),sin(c));
74             b=(b-p)*CD(cos(c),sin(c))+p;
75         }
76         double the=arg(k);
77         while (the<0) the+=2*pi;
78         while (the>=2*pi) the-=2*pi;
79         p=b/(CD(1,0)-k);
80         printf("%.10f %.10f %.10f\n",real(p),imag(p),the);
81     }
82 }

外来的代码君

时间: 2025-01-18 11:09:53

HDU 4998 (点的旋转) Rotate的相关文章

CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate)(转载)

在CSS3中,可以利用transform功能来实现文字或图像的旋转.缩放.倾斜.移动这四种类型的变形处理,本文将对此做详细介绍. 一.旋转 rotate 用法:transform: rotate(45deg); 共一个参数“角度”,单位deg为度的意思,正数为顺时针旋转,负数为逆时针旋转,上述代码作用是顺时针旋转45度. 二.缩放 scale 用法:transform: scale(0.5)  或者  transform: scale(0.5, 2); 参数表示缩放倍数: 一个参数时:表示水平和

变形--旋转 rotate()

变形--旋转 rotate() 旋转rotate()函数通过指定的角度参数使元素相对原点进行旋转.它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度.如果这个值为正值,元素相对原点中心顺时针旋转:如果这个值为负值,元素相对原点中心逆时针旋转.如下图所示: HTML代码: <div class="wrapper"> <div></div> </div> CSS代码: .wrapper { width: 200px; height

CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate)

CSS3属性transform详解之(旋转:rotate,缩放:scale,倾斜:skew,移动:translate) 在CSS3中,可以利用transform功能来实现文字或图像的旋转.缩放.倾斜.移动这四种类型的变形处理,本文将对此做详细介绍. 一.旋转 rotate 用法:transform: rotate(45deg); 共一个参数"角度",单位deg为度的意思,正数为顺时针旋转,负数为逆时针旋转,上述代码作用是顺时针旋转45度. 二.缩放 scale 用法:transform

HDU 4998 Rotate(计算几何 绕点旋转)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4998 Problem 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 every

hdu 4998 Rotate 点的旋转 银牌题

Rotate Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1232    Accepted Submission(s): 545Special Judge Problem Description Noting is more interesting than rotation! Your little sister likes to

HDU 4998 Rotate (几何变换——旋转)

Rotate Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 815    Accepted Submission(s): 389 Special Judge Problem Description Noting is more interesting than rotation! Your little sister likes to

HDU 4998 Rotate

Rotate Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 210    Accepted Submission(s): 110 Problem Description Noting is more interesting than rotation! Your little sister likes to rotate things

HDU 4998 Rotate --几何

题意:给n个点(x,y,p),从1~n,一次每次所有点绕着第 i 个点(原来的)逆时针转pi个弧度,问最后所有点的位置相当于绕哪个点旋转多少弧度,求出那点X和弧度P 解法:直接模拟旋转,每次计算新的坐标,最后选两个新的点分别和他们原来的点连一条线,两条线的中垂线的交点即为圆心,求出了圆心就可以求出转了多少弧度了. 注意判中垂线垂直x轴的情况以及n==1的情况. 最后角度要根据位置关系判下正负. 代码: #include <iostream> #include <cstdio> #i

HDU 4998 Rotate(计算几何)2014年鞍山赛区网络赛

Rotate                                                                           Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Special Judge Problem Description Noting is more interesting than rotation! Your litt