首页 > 代码库 > HDU 4998 Rotate

HDU 4998 Rotate

题意:

n次旋转  每次平面绕ai点旋转pi弧度  问  最后状态相当于初始状态绕A点旋转P弧度  A和P是多少

思路:

假设初始X点的最后状态为X‘点  则圆心一定在X和X‘连线的垂直平分线上  那么只要用在取一个点Y和Y‘  同样做它的垂直平分线  两线交点即是圆心  然后用简单几何方法算出角度  最后注意要求最后状态由最初状态逆时针旋转得到  适当调整角度即可

PS:

kuangbin巨巨的几何代码还是很容易理解的  非常好用~  谢谢~

代码:

#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\n", x);
	}
	return 0;
}


HDU 4998 Rotate