(第十二届山东省赛)JFootball Match(几何)

题目链接:登录—专业IT笔试面试备考平台_牛客网

 样例输入:

1
0 0 0 20

样例输出:

30.000000 20.000000 30.000000 -0.000000 15.000000 16.000000 16.347084 11.854102 20.706339 11.854102 17.179628 9.291796 18.526712 5.145898 15.000000 7.708204 11.473288 5.145898 12.820372 9.291796 9.293661 11.854102 13.652916 11.854102

 这是一道几何题目,我直接说思路吧,就是先把所给矩形的左下角坐标平移至原点,然后再把矩形的宽旋转至与y轴重合,这样的话比较容易计算五角星上的点的坐标,那怎样求解五角星上的点的坐标呢?先利用几何关系求出E点和F点的坐标,显然有E点和G点的夹角为72度,F点和H点的夹角也是72度,这样我们就可以利用E点和F点的坐标旋转得到G点和H点的坐标,同理可以得到其他在五角星上的点的坐标,当然为了简单起见,我们旋转的原点是五角星的中心,也就是说我们旋转之后得到的点的坐标是在以五角星中心为原点的坐标系中的,之后我们还要把这些点平移至以矩形左下角为原点的坐标系中,最后再进行一次旋转和平移得到原坐标系下的点的坐标,下面我们来说一下如何求得E和F的坐标(相对于五角星的中心),E的坐标很明显就是(0,r),假设五角星中心的点为O,那么有角OGF为18度,由于OG的长度也是r,那么F的纵坐标就是r*(sin18),又因为角FOE是36度,那么就有F的横坐标就是r*(sin18)*(tan36),这样我们就能够得到在以五角星中心为原点的坐标系下的E和F的坐标了,然后剩下的就是平移和旋转了,下面直接上代码

#include<bits/stdc++.h>
using namespace std;
#define pi (acos(-1)) 
const double eps=1e-8;
inline double f(double x)//角度转换为弧度 
{
	return x*pi/180;
} 
void change(double x,double y,double theta,double &nx,double &ny)//将(x,y)旋转theta(弧度制)后存入(nx,ny)中 
{
	theta*=-1;
	nx=x*cos(theta)-y*sin(theta);
	ny=x*sin(theta)+y*cos(theta);
}
double x[100],y[100];
int main(){
	int T;
	cin>>T;
	while(T--)
	{
		for(int i=0;i<2;i++) cin>>x[i]>>y[i];
		double tx=-x[0],ty=-y[0];//记录平移量 
		for(int i=0;i<2;i++) x[i]+=tx,y[i]+=ty;//对点进行平移 
		double theta=0;//theta为矩形的宽与y轴正向的夹角,也就是旋转角
		if(fabs(x[1])<eps)
		{
			if(y[1]>0) theta=0;
			else theta=acos(-1);
		}
		else if(fabs(y[1])<eps)
		{
			if(x[1]>0) theta = -acos(0);
			else theta=acos(0);
		}
		else if(x[1]>0&&y[1]>0)
			theta=atan(x[1]/y[1]);
		else if(x[1]>0&&y[1]<0)
			theta=acos(-1)+atan(x[1]/y[1]);
		else if(x[1]<0&&y[1]>0)
			theta=atan(x[1]/y[1]);
		else
			theta=atan(x[1]/y[1])-acos(-1);
		double height=sqrt(x[1]*x[1]+y[1]*y[1]);//计算矩形的高 
		x[0]=y[0]=0;
		x[1]=0;y[1]=height;
		x[2]=height*3/2,y[2]=height;
		x[3]=height*3/2;y[3]=0;
		double r=0.3*height;
		x[4]=0;y[4]=r;
		x[5]=r*cos(f(72))*tan(f(36));y[5]=r*cos(f(72));
		for(int i=6;i<=13;i+=2)//利用E,F旋转得到五角星上其余的点 
		{
			change(x[4],y[4],f(72*(i-4)/2),x[i],y[i]);
			change(x[5],y[5],f(72*(i-4)/2),x[i+1],y[i+1]);
		} 
		double mx=height*3/4,my=height/2;
		for(int i=4;i<=13;i++) x[i]+=mx,y[i]+=my;//将五角星上所有的点平移至以矩形左下角为原点的坐标系中 
		for(int i=0;i<=13;i++)//将所有点转移至原坐标系中 
		{
			change(x[i],y[i],theta,x[i],y[i]);
			x[i]-=tx;y[i]-=ty;
		}
		for(int i=2;i<=13;i++) printf("%.6lf %.6lf ",x[i],y[i]);
		puts("");
	}
	return 0;
}
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值