HDU 4998 Rotate --几何
题意:给n个点(x,y,p),从1~n,一次每次所有点绕着第 i 个点(原来的)逆时针转pi个弧度,问最后所有点的位置相当于绕哪个点旋转多少弧度,求出那点X和弧度P
解法:直接模拟旋转,每次计算新的坐标,最后选两个新的点分别和他们原来的点连一条线,两条线的中垂线的交点即为圆心,求出了圆心就可以求出转了多少弧度了。
注意判中垂线垂直x轴的情况以及n==1的情况。
最后角度要根据位置关系判下正负。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define pii acos(-1.0)
#define eps 1e-8
using namespace std;
#define N 17 typedef struct point
{
double x,y,radi;
int ind;
point(double x=,double y=):x(x),y(y){}
}Vector; struct Point
{
double x,y;
Point(double x = ,double y = ):x(x),y(y){ }
}; Vector pi[N];
Point np[N];
int n; int dcmp(double x)
{
if(fabs(x)<eps)
return ;
return x < ? -:;
}
Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (point A,point B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Vector A,double p){return Vector(A.x*p,A.y*p);}
Vector operator / (Vector A,double p){return Vector(A.x/p,A.y/p);}
bool operator == (const point& a,const point& b){return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;}
bool operator < (const point& a,const point& b){return a.x<b.x ||(a.x==b.x&&a.y<b.y);} //比较和排序可用
double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;} //叉积 ,大于零说明B在A的左边,小于零说明B在A的右边
double Dot(Vector A,Vector B){return A.x*B.x+A.y*B.y;} //点积
double Length(Vector A){return sqrt(Dot(A,A));} //向量长度
double Angle(Vector A,Vector B){return acos(Dot(A,B)/Length(A)/Length(B));};
Vector Rotate(Vector A,double rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}//rad为弧度,向量逆时针旋转rad int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=;i<=n;i++)
{
scanf("%lf%lf%lf",&pi[i].x,&pi[i].y,&pi[i].radi),pi[i].ind = i;
np[i].x = pi[i].x;
np[i].y = pi[i].y;
}
if(n == )
{
printf("%.10f %.10f %.10f\n",pi[].x,pi[].y,pi[].radi);
continue;
}
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
Vector k = Vector(np[j].x-pi[i].x,np[j].y-pi[i].y);
k = Rotate(k,pi[i].radi);
np[j].x = pi[i].x + k.x;
np[j].y = pi[i].y + k.y;
}
}
Point A,B,C,D;
A = Point(pi[].x,pi[].y);
B = np[];
C = Point(pi[].x,pi[].y);
D = np[];
Point Mid1 = Point((A.x+B.x)/2.0,(A.y+B.y)/2.0);
Point Mid2 = Point((C.x+D.x)/2.0,(C.y+D.y)/2.0);
double k1,k2;
double Ix,Iy;
if(dcmp(A.y-B.y) == )
{
if(dcmp(D.x-C.x) == )
k2 = 0.0;
else
{
k2 = (D.y-C.y)/(D.x-C.x);
k2 = -1.0/k2;
}
Ix = Mid1.x;
Iy = Mid2.y + k2*(Mid1.x-Mid2.x);
}
else if(dcmp(D.y-C.y) == )
{
if(dcmp(B.x-A.x) == )
k1 = 0.0;
else
{
k1 = (B.y-A.y)/(B.x-A.x);
k1 = -1.0/k1;
}
Ix = Mid2.x;
Iy = Mid1.y + k1*(Mid2.x-Mid1.x);
}
else
{
k1 = (B.y-A.y)/(B.x-A.x);
k1 = -1.0/k1;
k2 = (D.y-C.y)/(D.x-C.x);
k2 = -1.0/k2;
double b1 = -k1*Mid1.x + Mid1.y;
double b2 = -k2*Mid2.x + Mid2.y;
Ix = (b2-b1)/(k1-k2);
Iy = k1*Ix + b1;
}
Vector ka = Vector(pi[].x-Ix,pi[].y-Iy);
Vector kb = Vector(np[].x-Ix,np[].y-Iy);
double ang = Angle(ka,kb);
double coss = Cross(ka,kb);
if(dcmp(coss-0.0) == -)
ang = 2.0*pii-ang;
printf("%.10f %.10f %.10f\n",Ix,Iy,ang);
}
return ;
}
HDU 4998 Rotate --几何的更多相关文章
- HDU 4998 Rotate (计算几何)
HDU 4998 Rotate (计算几何) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4998 Description Noting is more ...
- HDU 4998 Rotate
题意: n次旋转 每次平面绕ai点旋转pi弧度 问 最后状态相当于初始状态绕A点旋转P弧度 A和P是多少 思路: 如果初始X点的最后状态为X'点 则圆心一定在X和X'连线的垂直平分线上 那 ...
- hdu 4998 Rotate 点的旋转 银牌题
Rotate Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
- HDU 4998 (点的旋转) Rotate
为了寻找等效旋转操作,我们任选两个点P0和Q0,分别绕这n个点旋转一定的角度后最终得到Pn和Qn 然后已知:P0和Pn共圆,Q0和Qn共圆.所以要找的等效旋转点就是这两个线段的垂直平分线交点O. 等效 ...
- hdu 4998
http://acm.hdu.edu.cn/showproblem.php?pid=4998 这道题,在比赛的时候看了很久,才明白题目的大意.都怪自己不好好学习英语.后来经过队友翻译才懂是什么意思. ...
- hdu 4998 矩阵表示旋转
http://acm.hdu.edu.cn/showproblem.php?pid=4998 http://blog.csdn.net/wcyoot/article/details/33310329 ...
- HDU 4629 Burning 几何 + 扫描线
总体思路参考了 这里. 细节:1.控制精度,虽然这题没卡精度,不过还是要控制一下. 之前 bool operator<( const Point& A, const Point& ...
- hdu 5839(三维几何)
Special Tetrahedron Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 4063 Aircraft --几何,最短路
题意: 给一些圆,要求从第一个圆的圆心走到最后一个圆的圆心,中间路径必须在某个圆内,求最短路径的长度. 解法: 易知要保持在圆内且路径最短,走两圆相交的点能使路径尽量短,所以我们找出所有的两圆相交的点 ...
随机推荐
- Android笔记——Android中数据的存储方式(三)
Android系统集成了一个轻量级的数据库:SQLite,所以Android对数据库的支持很好,每个应用都可以方便的使用它.SQLite作为一个嵌入式的数据库引擎,专门适用于资源有限的设备上适量数据存 ...
- 【GOF23设计模式】状态模式
来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_状态模式.UML状态图.酒店系统房间状态.线程对象状态切换 package com.test.state; public ...
- javascript函数中的三个技巧【一】
在学习javascript中,函数是非常重要的,现在我来谈谈对函数的理解以及在工作和用法中的一些技巧 技巧一. [作用域安全的构造函数] 构造函数其实就是一个使用new操作调用的函数 function ...
- NEC的学习笔记
写过很多代码后,会有代码的规范有一些需求,会有想写出美观.规范.易懂的代码. 今天学习了NEC,全称Nice Easy CSS(http://nec.netease.com/),顾名思义,就是为了写简 ...
- 为什么要选择Sublime Text3?
为什么要选择Sublime Text3? Sublime Text3 自动保存,打开图片 跨平台启动快!!!!多行游标,太好用. 插件,简直选不过来. 代码片段 VIM兼容模式 菜单栏基础功能介绍 F ...
- CRM 2013 Reporting Extensions for SSRS 安装及问题解决
说明一下 Reporting Extensions for SSRS 安装过程. 安装目录在安装目录下 SrsDataConnector 下.如果是CRM 2013安装中运行,可以跳过此步. 此外在说 ...
- SharePoint 服务器端对象模型 之 使用LINQ进行数据访问操作(Part 2)
(四)使用LINQ进行列表查询 在生成实体类之后,就可以利用LINQ的强大查询能力进行SharePoint列表数据的查询了.在传统SharePoint对象模型编程中,需要首先获取网站对象,再进行其他操 ...
- 【读书笔记】iOS-GCD-多线程编程
一,现在一个物理的CPU芯片实际上有64个(64核)CPU,如果1个CPU核虚拟为两个CPU核工作,那么一台计算机上使用多个CPU核就是理所当然的事了.尽管如此,“1个CPU核执行的CPU命令为一条无 ...
- mac os x使用Git简易入门教程
具体如下: 1, 首先要了解什么是Git. 简而言之,Git是一个分布式的代码版本管理工具.类似的常用工具还有SVN,CVS. 概念了解参见:http://baike.baidu.com/subvie ...
- iOS UIButton添加圆角,添加边框
//准备工作 UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(,, ...