码迷,mamicode.com
首页 > 其他好文 > 详细

【几何模板加点小思路】hdu-4998 Rotate

时间:2015-08-08 22:43:05      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:

用几何模板敲的,也有直接公式推的,追求短代码的可以点右上角小红了......

题意就是想想一个物体分别做绕某一点(给出坐标)旋转p度(给出角度)后,其位置等价于绕哪一点旋转多少度,输出该等价点及其等价角度。

其实就是找两个定点,然后看这两个定点旋转后到了哪,分别连接原点与旋转后的点会得到两条线段,两条线段垂直平分线的交点即是等价后绕其旋转的点,再将该交点与任一原点及其旋转后的点连接得到的夹角(咖啡色角)即等价后的旋转角度。

技术分享

 

附代码

技术分享
  1 #include <cstdio>
  2 #include <iostream>
  3 #include <sstream>
  4 #include <cmath>
  5 #include <cstring>
  6 #include <cstdlib>
  7 #include <string>
  8 #include <vector>
  9 #include <map>
 10 #include <set>
 11 #include <queue>
 12 #include <stack>
 13 #include <algorithm>
 14 using namespace std;
 15 #define ll long long
 16 #define _cle(m, a) memset(m, a, sizeof(m))
 17 #define repu(i, a, b) for(int i = a; i < b; i++)
 18 #define repd(i, a, b) for(int i = b; i >= a; i--)
 19 #define sfi(n) scanf("%d", &n)
 20 #define sfl(n) scanf("%lld", &n)
 21 #define pfi(n) printf("%d\n", n)
 22 #define pfl(n) printf("%lld\n", n)
 23 #define MAXN 6005
 24 const double eps = 1e-6;
 25 const double inf = 1e50;
 26 const double pi  = acos(-1.0);
 27 struct point
 28 {
 29     double x, y;
 30     point() {}
 31     point(double _x, double _y) : x(_x), y(_y) {}
 32     point operator - (const point& ne) const
 33     {
 34         return point(x-ne.x, y-ne.y);
 35     }
 36     point operator + (const point& ne) const
 37     {
 38         return point(x+ne.x, y+ne.y);
 39     }
 40 };
 41 struct line
 42 {
 43     point a, b;
 44     line() {}
 45     line(point _a, point _b):a(_a), b(_b) {}
 46 };
 47 point Rotate(point o, point p, double alpha) 求点o绕点o旋转alpha度(弧度)后的坐标值
 48 { 
 49     point tp;
 50     p.x -= o.x;
 51     p.y -= o.y;
 52     tp.x = p.x * cos(alpha) - p.y * sin(alpha) + o.x;
 53     tp.y = p.y * cos(alpha) + p.x * sin(alpha) + o.y;
 54     return tp;
 55 }
 56 
 57 double len(point p1, point p2)
 58 {
 59     return (p1.x*p1.x-p2.x*p2.x)+(p1.y*p1.y-p2.y*p2.y);
 60 }
 61 point solve(point p11, point p12, point p21, point p22) //解方程就中垂线交点
 62 {
 63     double k1 = len(p11, p12);
 64     double k2 = len(p21, p22);
 65     if(fabs(p11.y - p12.y) < eps)
 66     {
 67         double a = (p11.x+p12.x)/2;
 68         double b = p11.y;
 69         return point(a, b);
 70     }
 71     double tmp1 = (p21.y-p22.y)/(p11.y-p12.y);
 72     double res1 = (k2/2) - (k1/2)*tmp1;
 73     double tmp2 = (p21.x-p22.x) - (p11.x-p12.x)*tmp1;
 74     double a = res1 / tmp2;
 75     double b = ((k1/2) - a*(p11.x-p12.x)) / (p11.y - p12.y);
 76     return point(a, b);
 77 }
 78 inline double dmult(point a, point b)
 79 {
 80     return a.x * b.x + a.y * b.y;
 81 }
 82 inline double xmult(point o,point a,point b)
 83 {
 84     return (a.x - o.x) * (b.y - o.y) - (b.x - o.x)*(a.y - o.y);
 85 }
 86 double angle(point o, point s, point e) //求两线段夹角
 87 {
 88     point os = s-o, oe = e-o;
 89     double bot = sqrt(dmult(os, os) * dmult(oe, oe));
 90     double top = dmult(os, oe);
 91     double cosfi = top/bot;
 92     if(cosfi >= 1.0) return 0;
 93     if(cosfi <= -1.0) return -pi;
 94     double fi = acos(cosfi);
 95     if(xmult(o, s, e) > 0) return fi;
 96     else return 2*pi-fi;
 97 }
 98 double lsangle(line u, line v)
 99 {
100     point o(0, 0), a = u.b - u.a, b = v.b - v.a;
101     return angle(o, a, b);
102 }
103 int main()
104 {
105     int T; scanf("%d", &T);
106     while(T--)
107     {
108         int n; scanf("%d", &n);
109 
110         point p1(-1, 0), p2(0, -1), p3(0, 0); //其实取两个点就可以了
111         point t1(-1, 0), t2(0, -1), t3(0, 0); 
112         double pp;
113         for(int i = 0; i < n; i++)
114         {
115             double x, y, p;
116             scanf("%lf%lf%lf", &x, &y, &p);
117             if(fabs(p-0.0) < eps) continue;
118             point o(x, y);
119             p1 = Rotate(o, p1, p);
120             p2 = Rotate(o, p2, p);
121             p3 = Rotate(o, p3, p);
122             //printf("%lf %lf\n", p3.x, p3.y);
123             //pp += p;
124         }
125         if(fabs(p1.x - t1.x) < eps && fabs(p1.y - t1.y) < eps &&
126            fabs(p2.x - t2.x) < eps && fabs(p2.y - t2.y) < eps &&
127            fabs(p3.x - t3.x) < eps && fabs(p3.y - t3.y) < eps)
128         {
129             printf("%.10lf %.10lf %.10lf\n", 0.0, 0.0, 0.0);
130             continue;
131         }
132         point ans1 = solve(t1, p1, t2, p2);
133         if(fabs(ans1.x - 0.0) < eps) ans1.x = 0;
134         if(fabs(ans1.y - 0.0) < eps) ans1.y = 0;
135         //printf("%.10lf %.10lf %.10lf\n", ans1.x, ans1.y, pp);
136         line l1(ans1, t1), l2(ans1, p1);
137         double ang = lsangle(l1, l2);
138         printf("%.10lf %.10lf %.10lf\n", ans1.x, ans1.y, ang);
139     }
140     return 0;
141 }
View Code

 

【几何模板加点小思路】hdu-4998 Rotate

标签:

原文地址:http://www.cnblogs.com/LLGemini/p/4713888.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!