给出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; }