题意:
n次旋转 每次平面绕ai点旋转pi弧度 问 最后状态相当于初始状态绕A点旋转P弧度 A和P是多少
思路:
如果初始X点的最后状态为X‘点 则圆心一定在X和X'连线的垂直平分线上 那么仅仅要用在取一个点Y和Y' 相同做它的垂直平分线 两线交点即是圆心 然后用简单几何方法算出角度 最后注意要求最后状态由最初状态逆时针旋转得到 适当调整角度就可以
PS:
kuangbin巨巨的几何代码还是非常easy理解的 非常好用~ 谢谢~
代码:
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<set> #include<vector> #include<cassert> using namespace std; typedef long long LL; #define Q 401 #define N 51 #define M 200001 #define inf 2147483647 #define lowbit(x) (x&(-x)) const double eps = 1e-5; const double PI = acos(-1.0); int sgn(double x) { if (fabs(x) < eps) return 0; if (x < 0) return -1; else return 1; } struct Point { double x, y; Point() { } Point(double _x, double _y) { x = _x; y = _y; } Point operator +(const Point &b) const { return Point(x + b.x, y + b.y); } Point operator -(const Point &b) const { return Point(x - b.x, y - b.y); } //叉积 double operator ^(const Point &b) const { return x * b.y - y * b.x; } //点积 double operator *(const Point &b) const { return x * b.x + y * b.y; } //绕原点逆时针旋转角度B(弧度值)。后x,y的变化 void transXY(double B) { double tx = x, ty = y; x = tx * cos(B) - ty * sin(B); y = tx * sin(B) + ty * cos(B); } } a1, a2, b1, b2, f1, f2, f3; struct Line { Point s, e; Line() { } Line(Point _s, Point _e) { s = _s; e = _e; } //两直线相交求交点 //第一个值为0表示直线重合,为1表示平行,为2是相交 //仅仅有第一个值为2时。交点才有意义 pair<int, Point> operator &(const Line &b) const { Point res = s; if (sgn((s - e) ^ (b.s - b.e)) == 0) { if (sgn((s - b.e) ^ (b.s - b.e)) == 0) return make_pair(0, res); //重合 else return make_pair(1, res); //平行 } double t = ((s - b.s) ^ (b.s - b.e)) / ((s - e) ^ (b.s - b.e)); res.x += (e.x - s.x) * t; res.y += (e.y - s.y) * t; return make_pair(2, res); } } l1, l2; //两点间距离 double dist(Point a, Point b) { return sqrt((a - b) * (a - b)); } int t, n; int main() { int i; double x, y, z; scanf("%d", &t); while (t--) { a1 = f1 = Point(5e5, 3e5); a2 = f2 = Point(1e5, 6e5); scanf("%d", &n); for (i = 1; i <= n; i++) { scanf("%lf%lf%lf", &x, &y, &z); f3 = Point(x, y); f1 = f1 - f3; f2 = f2 - f3; f1.transXY(z); f2.transXY(z); f1 = f1 + f3; f2 = f2 + f3; } b1 = a1 + f1; b1.x /= 2; b1.y /= 2; b2 = f1; b2 = b2 - b1; b2.transXY(PI / 2); b2 = b2 + b1; l1 = Line(b1, b2); b1 = a2 + f2; b1.x /= 2; b1.y /= 2; b2 = f2; b2 = b2 - b1; b2.transXY(PI / 2); b2 = b2 + b1; l2 = Line(b1, b2); pair<int, Point> res = l1 & l2; i = res.first; f3 = res.second; assert(i == 2); printf("%f %f ", f3.x, f3.y); f2 = f1 + a1; f2.x /= 2; f2.y /= 2; x = atan(dist(f1, f2) / dist(f2, f3)) * 2; y = PI + PI; while (x > y) x -= y; while (x < 0) x += y; a1 = a1 - f3; a1.transXY(x); a1 = a1 + f3; a1 = a1 - f1; if (sgn(a1.x) || sgn(a1.y)) x = PI + PI - x; printf("%f ", x); } return 0; }