题意:

      一开始的时候有一个坐标系(正常的),然后有n个操作,每个操作是 x y d,意思是当前坐标系围绕x,y点逆时针旋转d度,最后让你输出三个数x y d,把这n个操作的最后结果,用一步等效过来,就是找到一个点,逆时针旋转一个度数,等于当前的这个状态。

思路:

      我们可以用一个向量来代表当前坐标系,每次操作把当前向量拆成两个点单独操作,假如当前向量a,b,绕点c旋转d度,那么我们可以等效向量c,a逆时针旋转d,然后向量c,b逆时针旋转d,这样就的到了两个新的向量,此时我们要根据这两个新的向量求出当前这两个点的新位置,然后再用当前的新位置和下一组操作,最后得到了最终的一个向量,现在我们只要求出初始向量和最终向量的转换关系就行了,这个地方首先我们求转换点,求法是两个向量的x,x'连线,y.y'连线,两条线段中垂线的交点,求出交点之后再用余弦定理求出夹角,然后在用向量的关系来判断要不要用2PI-当前度数,具体看代码。


#include<math.h>
#include<algorithm>
#include<stdio.h>
#define maxn 60
#define eps 1e-7
#define PP (3.141592653589793238)
using namespace std; int dcmp(double x)
{
if(
fabs(x)<eps) return 0;
else return
x<0?-1:1;
}
double
toRad(double deg)
{
return
deg/180.0*acos(-1.0);
}
struct
Point
{
double
x,y;
Point(){}
Point(double x,double y):x(x),y(y) {}
void
input()
{

scanf("%lf %lf",&x,&y);
}
};
typedef
Point Vector; Vector operator+( Vector A, Vector B )
{
return
Vector( A.x + B.x, A.y + B.y );
}

Vector operator-(Vector A,Vector 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 ) < 0 || ( dcmp( A.x - B.x ) == 0 && dcmp( A.y - B.y ) < 0 );
}
bool operator==( const
Point& a, const Point& b )
{
return
dcmp( a.x - b.x ) == 0 && dcmp( a.y - b.y ) == 0;
}
struct
Line
{

Point s,e;
Vector v;
Line() {}
Line(Point s,Point v,int type):
s(s),v(v){}
Line(Point s,Point e):s(s),e(e)
{
v=e-s;} };
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));
}
double
Cross(Vector A,Vector B)
{
return
A.x*B.y-A.y*B.x;
}
double
Area2(Point A,Point B,Point C )
{
return
Cross(B-A,C-A);
}
double
Dist(Point A,Point B)
{
return
Length(A-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));
}

Vector Normal(Vector A)
{
double
L=Length(A);
return
Vector(-A.y/L,A.x/L);
}

Point GetLineIntersection(Line l1,Line l2)
{

Point P=l1.s;
Vector v=l1.v;
Point Q=l2.s;
Vector w=l2.v;
Vector u=P-Q;
double
t=Cross(w,u)/Cross(v,w);
return
P+v*t;
}
double
DistanceToLine(Point P,Line L)
{

Point A,B;
A=L.s,B=L.e;
Vector v1=B-A,v2=P-A;
return
fabs(Cross(v1,v2))/Length(v1);
}
double
DistanceToSegment(Point P, Line L)
{

Point A,B;
A=L.s,B=L.e;
if(
A==B) return Length(P-A);
Vector v1=B-A,v2=P-A,v3=P-B;
if (
dcmp(Dot(v1,v2))<0) return Length(v2);
else if (
dcmp(Dot(v1,v3))>0) return Length(v3);
else return
fabs(Cross(v1,v2)) / Length(v1);
}

Point GetLineProjection(Point P,Line L)
{

Point A,B;
A=L.s,B=L.e;
Vector v=B-A;
return
A+v*(Dot(v,P-A)/Dot(v,v));
} double
abss(double x)
{
return
x < 0 ? -x : x;
} bool
OnSegment(Point p,Line l)
{

Point a1=l.s;
Point a2=l.e;
return
dcmp(Cross(a1-p,a2-p))==0&&dcmp(Dist(p,a1)+Dist(p,a2)-Dist(a1,a2))==0;
}
bool
Paralled(Line l1,Line l2)
{
return
dcmp(Cross(l1.e-l1.s,l2.e-l2.s))==0;
}
bool
SegmentProperIntersection(Line l1,Line l2)
{
if(
Paralled(l1,l2))
{
return
false;
}

Point t=GetLineIntersection(l1,l2);
if(
OnSegment(t,l1))
{
return
true;
}
return
false;
} int main ()
{
double
x ,y ,p;
int
T ,n ,i;
scanf("%d" ,&T);
while(
T--)
{

scanf("%d" ,&n);
double
nowx1 = 0 ,nowy1 = 0;
double
nowx2 = 0 ,nowy2 = 101.0;
double
sss = 0;;
Vector A ,B;
for(
i = 1 ;i <= n ;i ++)
{

scanf("%lf %lf %lf" ,&x ,&y ,&p);
if(
p == 0.0 || abss(p - PP * 2) <= 0.00001) continue;
sss += p;
A.x = nowx1 - x ,A.y = nowy1 - y;
B = Rotate(A ,p);
nowx1 = x + B.x ,nowy1 = y + B.y;
A.x = nowx2 - x ,A.y = nowy2 - y;
B = Rotate(A ,p);
nowx2 = x + B.x ,nowy2 = y + B.y;
}
if(
nowx1 == 0.0 && nowy1 == 0.0)
{
double
x4 = nowx2 ,y4 = nowy2;
double
x3 = 0 ,y3 = 0;
double
x1 = 0 ,y1 = 101.0;
double
aaa;
double
tmp = (x4 - x3) * (x1 - x3) + (y4 - y3) * (y1 - y3);
tmp = tmp / (pow(x4 - x3 ,2.0) + pow(y4 - y3 ,2.0));
aaa = acos(tmp);
double
q1 = 0 ,q2 = 0;
if(
nowx2 > 0.0) aaa = PP * 2 - aaa;
if(
abss(aaa - PP * 2) <= 0.00001)aaa = 0;
printf("%lf %lf %lf\n" ,q1 ,q2 ,aaa);
}
else if(
nowx2 == 0.0 && nowy2 == 101.0)
{
double
x4 = nowx1 ,y4 = nowy1;
double
x3 = 0 ,y3 = 101.0;
double
x1 = 0 ,y1 = 0;
double
aaa;
double
tmp = (x4 - x3) * (x1 - x3) + (y4 - y3) * (y1 - y3);
tmp = tmp / (pow(x4 - x3 ,2.0) + pow(y4 - y3 ,2.0));
aaa = acos(tmp);
double
q1 = 0 ,q2 = 101.0;
if(
nowx1 < 0) aaa = PP * 2 - aaa;
if(
abss(aaa - PP * 2) <= 0.00001)aaa = 0;
printf("%lf %lf %lf\n" ,q1 ,q2 ,aaa);
}
else
{

Point AA1;
AA1.x = AA1.y = 0;
Point BB1;
BB1.x = nowx1 ,BB1.y = nowy1;
Line now1 = Line((AA1 + BB1)/2 ,Normal(AA1 - BB1),1);
Point AA2;
AA2.x = 0 ,AA2.y = 101.0;
Point BB2;
BB2.x = nowx2 ,BB2.y = nowy2;
Line now2 = Line((AA2 + BB2)/2 ,Normal(AA2 - BB2),1);
Point now = GetLineIntersection(now1 ,now2);
double
x4 = nowx1 ,y4 = nowy1;
double
x3 = now.x ,y3 = now.y;
double
x1 = 0 ,y1 = 0;
double
aaa;
double
tmp = (x4 - x3) * (x1 - x3) + (y4 - y3) * (y1 - y3);
tmp = tmp / (pow(x4 - x3 ,2.0) + pow(y4 - y3 ,2.0));
double
x2 ,y2;
x1 = 0 ,y1 = 101;
x2 = nowx2 - nowx1 ,y2 = nowy2 - nowy1;
aaa = acos(tmp);
if(
x1*y2-x2*y1<0) aaa = PP * 2 - aaa;
printf("%lf %lf %lf\n" ,now.x ,now.y ,aaa);
}
}
return
0;
}

hdu4998 旋转坐标系的更多相关文章

  1. VPython—旋转坐标系

    使用arrow( )创建三个坐标轴代表一个坐标系,其中X0-Y0-Z0为参考坐标系(固定不动),X-Y-Z为运动坐标系,这两个坐标系原点重合,运动坐标系可以绕参考坐标系或其自身旋转.在屏幕上输出一个转 ...

  2. 【bzoj3170】[Tjoi 2013]松鼠聚会 旋转坐标系

    题目描述 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. 输入 ...

  3. 【bzoj2989】数列 KD-tree+旋转坐标系

    题目描述 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Mo ...

  4. [bzoj2989]数列_KD-Tree_旋转坐标系

    数列 bzoj-2989 题目大意:题目链接. 注释:略. 想法:显然,我们用x和a[x]两个值建立笛卡尔坐标系. 两个点之间的距离为曼哈顿距离. 修改操作就是插入... 查询操作就是查询一个点周围的 ...

  5. [SDOI2018]物理实验 set,扫描线,旋转坐标系

    [SDOI2018]物理实验 set,扫描线,旋转坐标系 链接 loj 思路 先将导轨移到原点,然后旋转坐标系,参考博客. 然后分线段,每段的贡献(三角函数值)求出来,用自己喜欢的平衡树,我选set. ...

  6. HDU 6538 Neko and quadrilateral(极角排序+旋转坐标系)

    这道题简直太好了,对于计算几何选手需要掌握的一个方法. 首先对于求解四边形面积,我们可以将四边形按对角线划分成两个三角形,显然此时四边形的面积最大最小值就变成了求解里这个对角线最近最远的点对. 对于此 ...

  7. Android canvas rotate():平移旋转坐标系至任意原点任意角度-------附:android反三角函数小结

    自然状态下,坐标系以屏幕左上角为原点,向右是x正轴,向下是y正轴.现在要使坐标系的原点平移至任一点O(x,y),且旋转a角度,如何实现? 交待下我的问题背景,已知屏幕上有两点p1和p2,构成直线l.我 ...

  8. 【bzoj3210】花神的浇花集会 旋转坐标系

    题目描述 在花老师的指导下,每周4都有一个集会活动,俗称“浇水”活动. 具体浇水活动详情请见BZOJ3153 但这不是重点 花神出了好多题,每道题都有两个参考系数:代码难度和算法难度 花神为了准备浇花 ...

  9. 【bzoj1604】[Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 旋转坐标系+并查集+Treap/STL-set

    题目描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个“群”.每只奶牛在吃草的时候有一个独一无二的位置坐标Xi,Yi(l≤Xi,Yi≤ ...

随机推荐

  1. 少走弯路之marshalsec的编译(RMI必备工具)

        0x00 实验环境 实验机:Ubuntu18(公网Linux系统) 0x01 安装包 私聊我博客将会第一时间提供安装包环境: 0x02 避坑指南 由上篇文章:https://www.cnblo ...

  2. 如何安装jenkins并简单的使用

    如何安装jenkins并使用 一.jenkins 简介: Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括 : 1.持续的软件版本发布/测试项目: 2.监控外部调用 ...

  3. 使用css3和javascript开发web拾色器实例

    本实例中的web拾色器功能使用css3实现页面效果,即在页面上显示的元素用css3样式来实现的.再使用js生成拾色器颜色数据,并控制各元素的鼠标事件.当事件作为反应时,获取到对应的数据并显示颜色值. ...

  4. 提升Idea启动速度与Tomcat日志乱码问题

    提升Idea启动速度与Tomcat日志乱码问题 前言 由于重装了一次Idea,所以有些设置时间就忘了,在此做个记录,以便以后忘记后可以来翻阅 Idea启动速度 一.将Idea所在的 安装文件夹 在wi ...

  5. Docker SDK api操作Docker

    下载包 go get "github.com/docker/docker/api/types" go get "github.com/docker/docker/clie ...

  6. ASP.NET跨域访问解决

    第一种: step1:添加引用(搜索CORS) step2: App_Start/WebApiConfig.cs中添加配置 step3: 在控制器中添加特性 第二种: 在App_Start/WebAp ...

  7. 【关系抽取-R-BERT】模型结构

    模型的整体结构 相关代码 import torch import torch.nn as nn from transformers import BertModel, BertPreTrainedMo ...

  8. net start MongoDB 服务没有响应控制功能。 请键入 NET HELPMSG 2186 以获得更多的帮助。

    我在 Windows 电脑上修改了 mongo.cfg 文件后 执行 net start mongodb 的时候,命令行出现了这个报错. 这个报错,有几种情况可以进行排查 1. 你的 mongod 命 ...

  9. JAVA 写一个方法,判断一个整数是否为素数

    1 import java.util.Scanner; 2 3 public class Question3 { 4 public static void main(String[] args) { ...

  10. [矩阵乘法]裴波拉契数列III

    [ 矩 阵 乘 法 ] 裴 波 拉 契 数 列 I I I [矩阵乘法]裴波拉契数列III [矩阵乘法]裴波拉契数列III Description 求数列f[n]=f[n-1]+f[n-2]+1的第N ...