zoukankan      html  css  js  c++  java
  • 算法生成卐和卍字图

          前面讲了算法生成道教的太极八卦图,这一节发个与佛教有关的卍字图。这个图形应该是我上学时课桌上刻的最多的三个符号之一,另外两个是"早"和五角星。卍梵文Svastika,武则天定音为万字;意译为吉祥海云,吉祥喜旋,为佛三十二相之一,也是八十种好之一;此为显现于佛及十地菩萨胸臆等处之德相。长阿含经卷一大本经、大萨遮尼乾子所说经卷六、大般若经卷三八一等均记载佛之胸前、手足、腰间等处有卍字。于今印度阿摩罗婆提(Ama-ravati)出土之佛足石,亦刻有数个卍字。纳粹德国的纳粹党标志为希特勒借用的标致,但纳粹党标志的方向是斜的和黑色,而传统信仰中代表吉祥美好的卍字符多是明亮的色彩。

          佛教传入华夏大地,卍和卐也便传到了中国,并且卍和卐也融入中华文化之中,从那以后汉字中有了卐合卍。其实这个卐合卍是一个字”万“而且是对称的,卐是右旋(代表胸前十字向自己右手旋转),卍为左旋(代表胸前的十字向自己左手旋转)。

       对于生成卍字的算法,比起八卦图要容易得多,整体思路是创建一个大个矩形,再用四个小矩形将其不需要的地方扣去。代码如下:

     1 struct Rect
     2 {
     3     float left;
     4     float right;
     5     float top;
     6     float bottom;
     7 };
     8 
     9 inline bool IsInRect(const Rect& rect, float x, float y)
    10 {
    11     return (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom);
    12 }
    13 
    14 unsigned int    CPixelSvastikaLeft::CalculatePixel(unsigned int x, unsigned int y)
    15 {
    16     float size = m_params[0];
    17     float width = m_params[1];
    18     float angle = m_params[2]*PI/180;
    19 
    20     unsigned int black = 0xff000000;
    21     unsigned int gray = 0xff808080;
    22 
    23     float i = x - 512.0f;
    24     float j = y - 512.0f;
    25 
    26     Rect rect    = {-size, size, -size, size};
    27     Rect rtLeft  = {-size, -width*0.5f, -size + width, -width*0.5f};
    28     Rect rtTop   = {width*0.5f, size - width, -size, -width*0.5f};
    29     Rect rtRight = {width*0.5f, size, width*0.5f, size - width};
    30     Rect rtDown  = {-size + width, -width*0.5f, width*0.5f, size};
    31 
    32     float _s = sinf(angle);
    33     float _c = cosf(angle);
    34     float ti, tj;
    35 
    36     ti = i*_c - j*_s;
    37     tj = i*_s + j*_c;
    38 
    39     if (!IsInRect(rect, ti, tj))
    40     {
    41         return gray;
    42     }
    43     else if (IsInRect(rtLeft, ti, tj) ||
    44              IsInRect(rtTop, ti, tj) ||
    45              IsInRect(rtRight, ti, tj) ||
    46              IsInRect(rtDown, ti, tj))
    47     {
    48         return gray;
    49     }
    50 
    51     return black;
    52 }

    另一个方向的卐字,只需要对上面代码做如下改动:

        Rect rtLeft  = {-size, -width*0.5f, width*0.5f, size - width};
        Rect rtTop   = {-size + width, -width*0.5f, -size, -width*0.5f};
        Rect rtRight = {width*0.5f, size, -size + width, -width*0.5f};
        Rect rtDown  = {width*0.5f, size - width, width*0.5f, size};

    相应软件:Why数学图像生成工具,在软件中可以调节卍字的宽度和旋转,如下图所示:

    在古典家具中,经常会看到卐和卍字,如窗户上.下面,我将卐卍连起来,画出分形的图像来:

    unsigned int    CPixelSvastikasSet::CalculatePixel(unsigned int x, unsigned int y)
    {
        const unsigned int size = 64;
    
        float width = m_params[0];
    
        unsigned int color = 0xffffe020;
        unsigned int gray = 0xff808080;
    
        int index = x/size + y/size;
    
        x %= size;
        y %= size;
    
        float half_size = size*0.5f;
        float i = x - half_size;
        float j = y - half_size;
    
        Rect rt1 = {-width*0.5f, width*0.5f, -half_size + width, half_size - width};
        Rect rt2 = {-half_size + width, half_size - width, -width*0.5f, width*0.5f};
    
        Rect rt3 = {-half_size + width, -half_size + 2*width, -half_size, -width*0.5f};
        Rect rt4 = {width*0.5f, half_size, -half_size + width, -half_size + 2*width};
        Rect rt5 = {half_size - 2*width, half_size - width, width*0.5f, half_size};
        Rect rt6 = {-half_size, -width*0.5f, half_size - 2*width, half_size - width};
    
        Rect rt7  = {-half_size + width, -half_size + 2*width, width*0.5f, half_size};
        Rect rt8  = {width*0.5f, half_size, half_size - 2*width, half_size - width};
        Rect rt9  = {half_size - 2*width, half_size - width, -half_size, -width*0.5f};
        Rect rt10 = {-half_size, -width*0.5f, -half_size + width, -half_size + 2*width};
    
        if (IsInRect(rt1, i, j) || IsInRect(rt2, i, j))
        {
            return color;
        }
        else 
        {
            if (index & 1)
            {
                if (IsInRect(rt3, i, j) ||
                    IsInRect(rt4, i, j) ||
                    IsInRect(rt5, i, j) ||
                    IsInRect(rt6, i, j))
                {
                    return color;
                }
            }
            else
            {
                if (IsInRect(rt7, i, j) ||
                    IsInRect(rt8, i, j) ||
                    IsInRect(rt9, i, j) ||
                    IsInRect(rt10, i, j))
                {
                    return color;
                }
            }
        }
    
        return gray;
    }

    在我的软件中,用户可以调节其宽度:

    相关文章:

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

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

  • 相关阅读:
    centos 系统时间设置
    centos6 centos7 配置开机启动服务
    centos6.9 samba配置
    vmware异常关闭后导致虚拟机无法打开问题解决办法
    try using -rpath or -rpath-link
    ZR#988
    提高十连测day3
    Atcoder ABC 141
    ZR#957
    ST表
  • 原文地址:https://www.cnblogs.com/WhyEngine/p/4063353.html
Copyright © 2011-2022 走看看