• HDU 4998 Rotate


    题意:

    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;
    }
    


  • 相关阅读:
    200行代码实现Mini ASP.NET Core
    使用Elastic APM监控你的.NET Core应用
    .NET西安社区「拥抱开源,又见 .NET:壹周年Party」活动简报
    西安7月21日「拥抱开源,又见.NET:壹周年Party」线下交流活动
    领域驱动设计(DDD)编码实践
    再谈领域驱动设计
    「拥抱开源, 又见 .NET」系列第三次线下活动简报
    西安活动 | 4月20日「拥抱开源,又见.NET :云时代 • 新契机」
    在Xunit中使用FsCheck
    rocketMq特性(features)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5058803.html
Copyright © 2020-2023  润新知