Archipelago - SGU 120(计算几何向量旋转)

题目大意:有一个正N边形,然后给出两个点,求出剩余的点的坐标。

分析:向量旋转可以求出坐标,顺时针旋转时候,x = x'*cos(a) + y'*sin(a), y=-x'*sin(a) + y'*cos(a), 逆时针时候 x = x'*cos(a)-y'*sin(a), y=x'*sin(a)+y'*cos(a)。题目中先求出来圆心,然后再求剩余的点,不过求圆心的时候一定注意判断一下两点的角度是否大于PI。

 

代码如下:

==========================================================================================================

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;

const int MAXN = 1007;
const double PI = acos(-1.0);
const double EPS = 1e-7;

struct point
{
    double x, y;
    point(double x=0, double y=0):x(x),y(y){}
    point operator - (const point &tmp)const{
        return point(x-tmp.x, y-tmp.y);
    }
    double operator *(const point &tmp)const{
        return x*tmp.x+y*tmp.y;
    }
};
double Dis(point a, point b)
{
    return sqrt((a-b)*(a-b));
}
struct segment
{
    point s, e;
    segment(point s=0, point e=0):s(s),e(e){}

    point Turn(double len, double a)
    {///线段绕点s旋转a角度后长len的坐标,顺时针
        point t = e-s, ans;
        double len1 = Dis(s, e);
      ///  printf("sin(a)=%lf, cos(a)=%lf\n", sin(a), cos(a));
        ans.x = s.x + (t.y*sin(a)+t.x*cos(a))*len/len1;
        ans.y = s.y + (-t.x*sin(a)+t.y*cos(a))*len/len1;

        return ans;
    }
};

int main()
{
    point p[MAXN];
    int N, A, B;
    scanf("%d%d%d", &N, &A, &B);
    A-= 1, B-=1;
    scanf("%lf%lf%lf%lf", &p[A].x, &p[A].y, &p[B].x, &p[B].y);

    if(A > B)swap(A, B);

    double a, b, R;
    segment L;

    if(B-A >= N/2)
    {///夹角大于PI
        a = PI * 2 / N;
        b = PI/2 - a * (N-(B-A)) / 2;
        L.s = p[B], L.e = p[A];
    }
    else
    {
        a = PI * 2 / N;
        b = PI/2 - a * (B-A) / 2;
        L.s = p[A], L.e = p[B];
    }

    R = Dis(L.s, L.e) / 2 / cos(b);
    point heart = L.Turn(R, b);

    L.s = heart;

    for(int i=0; i<N; i++)
    {
        L.e = p[(A+i)%N];
        p[(A+i+1)%N] = L.Turn(R, a);
    }

    for(int i=0; i<N; i++)
    {
        if(fabs(p[i].x) <= EPS)p[i].x = EPS;
        if(fabs(p[i].y) <= EPS)p[i].y = EPS;
        printf("%.6f %.6f\n", p[i].x+1e-10, p[i].y+1e-10);
    }

    return 0;
}

 

posted @ 2015-09-23 15:12  无忧望月  阅读(265)  评论(0编辑  收藏  举报
levels of contents