zoukankan      html  css  js  c++  java
  • 算法生成五星红旗

          这一篇将提供一套生成五星红旗的算法,代码中满满都是正能量。上一篇文章是生成N芒星,五角星是就芒星的一种,所以不难生成一个五角星的图像。中华人民共和国国旗是五星红旗,旗面为红色,长宽比例为3:2。左上方缀黄色五角星五颗,四颗小星环拱在一颗大星的右面,并各有一个角尖正对大星的中心点。1、4颗黄星对齐,2、3颗黄星对齐。

    代码如下:

    h

     1 class CPixel5StarsRedFlag : public IPixelEquation
     2 {
     3 public:
     4     CPixel5StarsRedFlag();
     5 
     6     const char*     GetName() const
     7     {
     8         return "Five Stars Red Flag";
     9     }
    10 
    11     unsigned int    CalculatePixel(unsigned int x, unsigned int y);
    12 
    13     struct Star
    14     {
    15         float posX;
    16         float posY;
    17         float radius;
    18         float angle;
    19     };
    20     bool            IsPointInStar(float x, float y, Star& star);
    21 
    22 private:
    23     float m_list_sin[5];
    24     float m_list_cos[5];
    25 
    26     Star m_list_stars[5];
    27 };

          头文章中定义了一个结构体Star,用于决定五角星的位置,大小,旋转角度。需要为每一颗星设置其合适的数值,我提供的代码所用参数是我多次试出来的,与实际不会绝对地相符。

    cpp

      1 CPixel5StarsRedFlag::CPixel5StarsRedFlag()
      2 {
      3     m_width = 1680;
      4     m_height = 1120;
      5 
      6     for (int i = 0; i < 5; i++)
      7     {
      8         m_list_sin[i] = sinf((i - 0.5f)*2*PI/5);
      9         m_list_cos[i] = cosf((i - 0.5f)*2*PI/5);
     10     }
     11 
     12     m_list_stars[0].posX = m_width*0.2f;
     13     m_list_stars[0].posY = m_height*0.35f;
     14     m_list_stars[0].radius = m_height*0.1f;
     15     m_list_stars[0].angle = 0.0f;
     16 
     17     float r = m_list_stars[0].radius * 3.0f;
     18 
     19     m_list_stars[1].posX = m_list_stars[0].posX + r*cosf(PI/4);
     20     m_list_stars[1].posY = m_list_stars[0].posY + r*sinf(PI/4);
     21     m_list_stars[1].radius = m_list_stars[0].radius*0.5f;
     22     m_list_stars[1].angle = -PI/8;
     23 
     24     m_list_stars[2].posX = m_list_stars[0].posX + r*cosf(PI/12);
     25     m_list_stars[2].posY = m_list_stars[0].posY + r*sinf(PI/12);
     26     m_list_stars[2].radius = m_list_stars[0].radius*0.5f;
     27     m_list_stars[2].angle = -PI/24;
     28 
     29     m_list_stars[3].posX = m_list_stars[0].posX + r*cosf(-PI/12);
     30     m_list_stars[3].posY = m_list_stars[0].posY + r*sinf(-PI/12);
     31     m_list_stars[3].radius = m_list_stars[0].radius*0.5f;
     32     m_list_stars[3].angle = PI/24;
     33 
     34     m_list_stars[4].posX = m_list_stars[0].posX + r*cosf(-PI/4);
     35     m_list_stars[4].posY = m_list_stars[0].posY + r*sinf(-PI/4);
     36     m_list_stars[4].radius = m_list_stars[0].radius*0.5f;
     37     m_list_stars[4].angle = PI/8;
     38 }
     39 
     40 bool            CPixel5StarsRedFlag::IsPointInStar(float x, float y, Star& star)
     41 {
     42     float i = x - star.posX;
     43     float j = y - star.posY;
     44 
     45     if (i*i + j*j > star.radius*star.radius)
     46     {
     47         return false;
     48     }
     49 
     50     float _s = sinf(star.angle);
     51     float _c = cosf(star.angle);
     52 
     53     Vec2 P;
     54     P.x = i*_c - j*_s;
     55     P.y = i*_s + j*_c;
     56 
     57     Vec2 listPoints[5];
     58     for (unsigned int m = 0; m < 5; m++)
     59     {
     60         listPoints[m].x = star.radius*m_list_sin[m];
     61         listPoints[m].y = star.radius*m_list_cos[m];
     62     }
     63 
     64     bool bCenter = true;
     65     for (unsigned int m = 0; m < 5; m++)
     66     {
     67         Vec2& v = listPoints[m];
     68         Vec2& vL1 = listPoints[(m + 4)%5];
     69         Vec2& vL2 = listPoints[(m + 3)%5];
     70         Vec2& vR1 = listPoints[(m + 1)%5];
     71         Vec2& vR2 = listPoints[(m + 2)%5];
     72 
     73         if (!IsPointInAngle(vL2, v, vR2, P))
     74         {
     75             bCenter = false;
     76         }
     77         else if (IsSameSide(vL1, vR1, v, P))
     78         {
     79             return true;
     80         }
     81     }
     82 
     83     return bCenter;
     84 }
     85 
     86 unsigned int    CPixel5StarsRedFlag::CalculatePixel(unsigned int x, unsigned int y)
     87 {
     88     unsigned int red = 0xffff0000;
     89     unsigned int yellow = 0xfffff000;
     90 
     91     float i = (float)x;
     92     float j = (float)y;
     93 
     94     for (unsigned int m = 0; m < 5; ++m)
     95     {
     96         if (IsPointInStar(i, j, m_list_stars[m]))
     97         {
     98             return yellow;
     99         }
    100     }
    101 
    102     return red;
    103 }

    基类IPixelEquation的代码见:Why数学图像生成工具

    关于结构体Vec2的定义及相关函数见:二维平面上判断点在三角形内的最优算法

    代码中没有太考究图形之间的比例,与实际会略有不符。生成图像如下:

    相应软件:

    Why数学图像生成工具

    相关文章:

    算法生成青天白日满地红旗

    算法之美---100幅由程序生成的图像,总有一幅让你感到惊艳[上]

    算法之美---100幅由程序生成的图像,总有一幅让你感到惊艳[下]

    -------------------------------------------------------

          我本没打算太考究国旗的细节,但既然有网友指出了,那就做到完美吧。

    绘制方法标准
    Construction sheet of Flag of the People's Republic of China.svg
    1. 先将旗面划分为4个等分长方形,再将左上方长方形划分长宽15×10个方格。
    2. 大五角星的中心位于该长方形上5下5、左5右10之处。大五角星外接圆的直径为6单位长度。
    3. 四颗小五角星的中心点,第一颗位于上2下8、左10右5,第二颗位于上4下6、左12右3,第三颗位于上7下3、左12右3,第四颗位于上9下1、左10右5之处。
    4. 每颗小五角星外接圆的直径均为2单位长度。四颗小五角星均有一角尖正对大五角星的中心点。

    修改了下它的构造函数:

    CPixel5StarsRedFlag::CPixel5StarsRedFlag()
    {
        m_width = 1680;
        m_height = 1120;
    
        for (int i = 0; i < 5; i++)
        {
            m_list_sin[i] = sinf((i - 0.5f)*2*PI/5);
            m_list_cos[i] = cosf((i - 0.5f)*2*PI/5);
        }
    
        float cellSize = m_height/20.0f;
        float disX;
        float disY;
    
        m_list_stars[0].posX = cellSize*5.0f;
        m_list_stars[0].posY = cellSize*5.0f;
        m_list_stars[0].radius = cellSize*3.0f;
        m_list_stars[0].angle = 0.0f;
    
        float r = m_list_stars[0].radius * 3.0f;
    
        m_list_stars[1].posX = cellSize*10.0f;
        m_list_stars[1].posY = cellSize*2.0f;
        m_list_stars[1].radius = m_list_stars[0].radius/3.0f;
        disX = m_list_stars[0].posX - m_list_stars[1].posX;
        disY = m_list_stars[0].posY - m_list_stars[1].posY;
        m_list_stars[1].angle = PI + atan2f(disX, disY);
    
        m_list_stars[2].posX = cellSize*12.0f;
        m_list_stars[2].posY = cellSize*4.0f;
        m_list_stars[2].radius = m_list_stars[1].radius;
        disX = m_list_stars[0].posX - m_list_stars[2].posX;
        disY = m_list_stars[0].posY - m_list_stars[2].posY;
        m_list_stars[2].angle = PI + atan2f(disX, disY);
    
        m_list_stars[3].posX = cellSize*12.0f;
        m_list_stars[3].posY = cellSize*7.0f;
        m_list_stars[3].radius = m_list_stars[1].radius;
        disX = m_list_stars[0].posX - m_list_stars[3].posX;
        disY = m_list_stars[0].posY - m_list_stars[3].posY;
        m_list_stars[3].angle = PI + atan2f(disX, disY);
    
        m_list_stars[4].posX = cellSize*10.0f;
        m_list_stars[4].posY = cellSize*9.0f;
        m_list_stars[4].radius = m_list_stars[1].radius;
        disX = m_list_stars[0].posX - m_list_stars[4].posX;
        disY = m_list_stars[0].posY - m_list_stars[4].posY;
        m_list_stars[4].angle = PI + atan2f(disX, disY);
    }

  • 相关阅读:
    商品尺码规格和颜色需要支持双引号
    php xss 函数
    yar 调用rpc方法
    【转】Linux常用命令大全
    【Netty】最透彻的Netty原理架构解析
    【Git项目管理】分布式 Git
    【SpringBoot】几种定时任务的实现方式
    【Elasticsearch-Java】Java客户端搭建
    【Git项目管理】Git分支
    【Git项目管理】git新手入门——基础教程
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4065745.html
Copyright © 2011-2022 走看看