给出n正多边形的两个顶点坐标n1,n2,求其余顶点坐标。
1、先求出中心坐标C。
2、根据中心坐标C和初始的一个顶点,进行一定角度的旋转,依次求出其他顶点。
对于1:由两点n1,n2(不妨设n2>n1)和中心可形成一个三角形,已知两点坐标,可求该三角形的一边长y以及其它两边与中心所形成的夹角a=2π/n*(n2-n1),另外两个角相等,设为B,亦可求矣。
然后根据余弦定理求另一边x,这样初始两点形成的边,以n2为中心逆时针旋转B,即到达中心与n2形成的边的位置,然后乘以比例x/y即可得到中心与n2形成的向量。然后可求中心坐标。
关于向量的旋转:
我们对向量进行旋转变换可以通过矩阵完成,比如我要向量(x, y)绕原点逆时针旋转角度A:
[x, y] x [cosA sinA] = [x*cosA-y*sinA x*sinA+y*cosA]
[-sinA cosA]
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 160
#define Pi acos(-1.0)
typedef double db;
struct P
{
db x,y;
}p[N];
P rol(P s,P e,db a,db k) //向量se,逆时针旋转a度后,乘上比例系数k,返回新的终点坐标
{
P c;
db x=e.x-s.x,y=e.y-s.y;
c.x=s.x+k*(x*cos(a)-y*sin(a));
c.y=s.y+k*(x*sin(a)+y*cos(a));
return c;
}
P getc(P p1,P p2,int n1,int n2,int n) //获取中心坐标
{
db B=Pi*(0.5-1.0*(n2-n1)/n);
return rol(p2,p1,B,0.5/cos(B));
}
int main()
{
int i,n,n1,n2;
scanf("%d%d%d",&n,&n1,&n2);
scanf("%lf%lf%lf%lf",&p[n1].x,&p[n1].y,&p[n2].x,&p[n2].y);
if(n1>n2) swap(n1,n2); //注意这里的n1,n2不一定按顺序给出
P c=getc(p[n1],p[n2],n1,n2,n);
db deg=2.0*Pi/n;
for(i=1;i<n;++i)
{
int j=(n1+i)%n;
if(j==0) j=n;
if(j==n2) continue;
db tem=-deg*i; //相当于顺时针旋转deg*i度
p[j]=rol(c,p[n1],tem,1);
}
for(i=1;i<=n;++i) printf("%.6lf %.6lf\n",p[i].x,p[i].y);
return 0;
}