SGU 120 Archipelago (向量旋转)

来源:互联网 发布:淘宝图像识别 编辑:程序博客网 时间:2024/06/10 05:59

给出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]

      旋转后的向量为:[x*cosA-y*sinA  x*sinA+y*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;}



0 0
原创粉丝点击