四等分的角度 几何
程序员文章站
2022-06-03 19:34:46
...
题目链接:https://ac.nowcoder.com/acm/contest/5403/F
比赛时候遇到的题目,无奈高中几何知识已经全还给老师了QAQ。
题目大意:给你A,O,B三点的坐标,然后让你随便找出三个点K1,K2,K3使得射线OK1,OK2,OK3能够四等分∠AOB。
前置知识:变换矩阵(百度如下)
余弦定理(百度如下)
学会这两个前置知识这题求解便会如鱼得水一般。
解题思路:
1.因为变换矩阵只适用于是绕原点逆时针旋转,所以我们先将∠AOB移动到原点。
2.把∠AOB求出来,用余弦定理。
double dis(node p,node q)//求两点距离
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
double get_angle(node aa,node oo,node bb)//余弦定理求角度
{
double ao=dis(aa,oo),ab=dis(aa,bb),bo=dis(bb,oo);
return acos((ao*ao+bo*bo-ab*ab)/(2*ao*bo));
}
3.找到以哪条边逆时针旋转。
4.逆时针旋转3/4,1/2,1/4,利用变换矩阵求出对应点。
node solve(node aa,double angle)
{
double x=cos(angle)*aa.x-sin(angle)*aa.y;
double y=sin(angle)*aa.x+cos(angle)*aa.y;
return {x,y};
}
5.输出K1,K2,K3坐标,要求从A->B输出,所以从B开始逆时针旋转的要逆序输出。
完整AC代码如下
#include <bits/stdc++.h>
using namespace std;
struct node
{
double x,y;
}a,o,b;
double dis(node p,node q)
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
double get_angle(node aa,node oo,node bb)
{
double ao=dis(aa,oo),ab=dis(aa,bb),bo=dis(bb,oo);
return acos((ao*ao+bo*bo-ab*ab)/(2*ao*bo));
}
node solve(node aa,double angle)
{
double x=cos(angle)*aa.x-sin(angle)*aa.y;
double y=sin(angle)*aa.x+cos(angle)*aa.y;
return {x,y};
}
int main()
{
scanf("%lf %lf",&a.x,&a.y);
scanf("%lf %lf",&o.x,&o.y);
scanf("%lf %lf",&b.x,&b.y);
node tmp=o;
a.x-=o.x,a.y-=o.y,b.x-=o.x,b.y-=o.y;//将o移到原点
o.x-=o.x,o.y-=o.y;
double angle=get_angle(a,o,b);
bool opt;
node ans;
if((a.y>=0&&b.y>=0)||(a.y<=0&&b.y<=0))//判断以哪条边逆时针旋转
{
if(a.y>=0&&b.y>=0)
{
if(get_angle(a,o,{1,0})>get_angle(b,o,{1,0}))
ans=b,opt=1;
else
ans=a,opt=0;
}
else
{
if(get_angle(a,o,{1,0})<get_angle(b,o,{1,0}))
ans=b,opt=1;
else
ans=a,opt=0;
}
}
else
{
if(a.y>0)
{
if(get_angle(b,o,{1,0})>get_angle({-a.x,-a.y},o,{1,0}))
ans=a,opt=0;
else
ans=b,opt=1;
}
else if(b.y>0)
{
if(get_angle(a,o,{1,0})>get_angle({-b.x,-b.y},o,{1,0}))
ans=b,opt=1;
else
ans=a,opt=0;
}
}
node res1,res2,res3;
res1=solve(ans,angle*3/4);
res2=solve(ans,angle/2);
res3=solve(ans,angle/4);
if(opt)
{
printf("%lf %lf\n",res1.x+tmp.x,res1.y+tmp.y);//答案要把o点移回去哦 >_<
printf("%lf %lf\n",res2.x+tmp.x,res2.y+tmp.y);
printf("%lf %lf\n",res3.x+tmp.x,res3.y+tmp.y);
}
else
{
printf("%lf %lf\n",res3.x+tmp.x,res3.y+tmp.y);
printf("%lf %lf\n",res2.x+tmp.x,res2.y+tmp.y);
printf("%lf %lf\n",res1.x+tmp.x,res1.y+tmp.y);
}
return 0;
}
推荐阅读
-
cdr怎么把一个圆等分成四份? coreldraw等分圆的技巧
-
几何画板怎么绘制指定长度的线段或角度?
-
几何画板绘制出的角度怎么标上数字标记?
-
计算机图形学(四)几何变换_5_三维空间的几何变换_1_三维平移
-
ai怎么把一个圆四等分? ai等分圆形并填充颜色的技巧
-
四等分的角度 几何
-
cdr怎么把一个圆等分成四份? coreldraw等分圆的技巧
-
11 一道几何题,众所周知,坠帅坠可爱的ZZZ学长是计算几何的大师,这次他遇到了这样一个题目。 给定3个点a,b,c 找到一个点,使得如果我们把平面绕着这个点旋转一定的角度,a可以落在b原来的位置,
-
我的狗子-业余四足机器人笔记(2)-单腿逆解(几何法)
-
ai怎么把一个圆四等分? ai等分圆形并填充颜色的技巧