Rolling The Polygon Gym - 102222B

Rolling The Polygon Gym - 102222B

题意:

给你一个多边形,给你内部一个点Q,多边形在平面上滚动一周(当有一个边第二次触地滚动停止),问Q的轨迹长度

题解:

计算几何题目
自己一直不是很擅长也不是很想做,嫌麻烦,但是考了n次自己也不会n次,所以决定跳出舒适圈,开始攻克计算几何
我们注意多边形和目标点滚动的方式和轨迹,Q点每次移动轨迹都是一段弧,要求弧长就要知道半径和移动角度。
如图一次滚动,我们可以看出滚动角的顶点是p1,滚动角是p1,p2和p1,p3形成的夹角α,旋转角度就是180°-滚动角
因为都是一个图形内,所以其他边旋转角度是多少,Q就是多少。
现在知道Q的旋转角度,半径更好求就是Q到p1的距离
因为每个顶点都会是滚动角的顶点,所以求出Q到各顶点的距离,以及各个角
详细看代码
在这里插入图片描述

代码:

#include<bits/stdc++.h>
#define pii pair<int,int>
typedef long long ll;
using namespace std;
inline int read(){
    
    
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){
    
    if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const double PI=acos(-1.0);
double dis(pii x,pii y){
    
    
	return sqrt((x.first-y.first)*(x.first-y.first)+(x.second-y.second)*(x.second-y.second));
}
double angle(double r,pii x,pii y, pii z){
    
    
	double a=dis(y,z),b=dis(x,z),c=dis(x,y);
	double radian=acos(1.0*(a*a+c*c-b*b)/(2*a*c));
	return r*(PI-radian);
}
int main()
{
    
    
	int t,n,x,y;
	cin>>t;
	int cas=0;
	while(t--)
	{
    
    
		int n;
		cin>>n;
		vector<pii >v(n);
		for(int i=0;i<n;i++){
    
    
			cin>>x>>y;
			v[i]={
    
    x,y};
		}
		double ans=0.0;
		cin>>x>>y;
		for(int i=0;i<n;i++){
    
    
			double r=dis({
    
    x,y},v[i]);
			ans+=angle(r,v[(i-1+n)%n],v[i],v[(i+1+n)%n]);
		}
		printf("Case #%d: %.3f\n",++cas,ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35975367/article/details/115439764