zoukankan      html  css  js  c++  java
  • Archipelago

    题目大意:有一个正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
    ", 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
    ", p[i].x+1e-10, p[i].y+1e-10);
        }
    
        return 0;
    }
  • 相关阅读:
    [leetcode] Maximum Depth of Binary Tree
    [leetcode] Binary Tree Zigzag Level Order Traversal
    [leetcode] Binary Tree Level Order Traversal
    软工第二次极限测试
    动手动脑的问题以及课后实验性的问题3
    计算几何--半平面交与平面区域
    拉格朗日插值法
    计算几何--最小圆覆盖与最小球覆盖
    计算几何--圆与球
    程序员修炼之道读后感1
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4832349.html
Copyright © 2011-2022 走看看