标签:
用几何模板敲的,也有直接公式推的,追求短代码的可以点右上角小红了......
题意就是想想一个物体分别做绕某一点(给出坐标)旋转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 }
标签:
原文地址:http://www.cnblogs.com/LLGemini/p/4713888.html