原创 写代码的篮球球痴 嵌入式Linux 2020-12-26

收录于话题

#C语言65

#数据结构5

#嵌入式54

谢宾斯基三角形是一个有意思的图形,(英语:Sierpinski triangle)是一种分形,由波兰数学家谢尔宾斯基在1915年提出,它是一种典型的自相似集


c语言画谢宾斯基三角形_C语言


先画一个三角形,然后呢,取三角形的中点,组成一个新的三角形,把新的三角形挖空。


依次递归,就出现了后面的那个图形。


如果用C语言来画一个这样的三角形,我们需要怎么画呢?


我们先看看这样一段代码,思路还是跟之前一样,在屏幕上画出一个矩形,x行和y列。


#include <stdio.h>
#include <time.h>
#include <sys/select.h>
 
#define SIZE (1 << 5)/*64*/

/* 毫秒级 延时 */
void msleep(int ms)
{
 struct timeval delay;
 delay.tv_sec = 0;
 delay.tv_usec = ms * 1000; // 20 ms
 select(0, NULL, NULL, NULL, &delay);
}

int main()
{
 int x, y, i;
    printf("%d\n",SIZE);
    /*y用来控制列数*/
 for (y = SIZE - 1; y >= 0; y--, msleep(20),putchar('\n')) {
  /*控制行输出*/
        for (i = 0; i < y; i++) {msleep(20);putchar('^');}
 }
 return 0;
}


代码输出

为了方便大家观看,我做了一些调整



为了测试,我把代码改成这样,方便大家看到输出。

#include <stdio.h>

#define SIZE (1 << 3)
int main()
{
 int x, y, i;
    printf("%d\n",SIZE);
    /*y用来控制列数*/
 for (y = SIZE - 1; y >= 0; y--,putchar('\n')) {
  /*控制行输出*/
        for (i = 0; i < y; i++) {putchar('^');}
            for (x = 0; x + y < SIZE; x++){
                putchar('#');
            }
 }
 return 0;
}


代码输出

weiqifa@bsp-ubuntu1804:~/c$ gcc shengdanshu.c && ./a.out
8
^^^^^^^#
^^^^^^##
^^^^^###
^^^^####
^^^#####
^^######
^#######
########
weiqifa@bsp-ubuntu1804:~/c$

这里可以好好分析一下


y 长度是用来控制输出多少行,可以看到一共有 8 行。

i  的长度是用来输出 ^ 字符的,这个字符随着 y的减少也会相应减小。

x 也受到y 的限制,主要是在另一半输出 # 号字符。



知道了上面,我们来看看核心代码


#include <stdio.h>

#define SIZE (1 << 3)
int main()
{
 int x, y, i;
    printf("%d\n",SIZE);
    /*y用来控制列数*/
 for (y = SIZE - 1; y >= 0; y--,putchar('\n')) {
  /*控制行输出*/
        for (i = 0; i < y; i++) {putchar('^');}
            for (x = 0; x + y < SIZE; x++){
                printf((x & y) ? " " : "*");
            }
 }
 return 0;
}


代码输出

8
^^^^^^^*
^^^^^^**
^^^^^* *
^^^^****
^^^*   *
^^**  **
^* * * *
********


已经有了我们题目上所的三角形的模样了,这里只要再稍微修改下,就可以得到我们题目中所的那样的三角形了。不对称的原因主要是因为字符高度是宽度的两倍。


代码修改成这样

#include <stdio.h>

#define SIZE (1 << 3)
int main()
{
 int x, y, i;
    printf("%d\n",SIZE);
    /*y用来控制列数*/
 for (y = SIZE - 1; y >= 0; y--,putchar('\n')) {
  /*控制行输出*/
        for (i = 0; i < y; i++) {putchar('^');}
            for (x = 0; x + y < SIZE; x++){
                printf((x & y) ? "  " : "* ");
            }
 }
 return 0;
}

代码输出

weiqifa@bsp-ubuntu1804:~/c$ gcc shengdanshu.c && ./a.out
8
^^^^^^^*
^^^^^^* *
^^^^^*   *
^^^^* * * *
^^^*       *
^^* *     * *
^*   *   *   *
* * * * * * * *
weiqifa@bsp-ubuntu1804:~/c$


然后我们把 ^ 字符替换成空格,也就是我们想要的东西了。


然后空格和 * 的字符输出,主要是靠 x & y 来控制的,他们又是如何控制的呢?


我们计算一下上面的算法

c语言画谢宾斯基三角形_C语言_02


绿色的地方是我们输出 * 字符的位置,蓝色的 是我们输出 空格的位置,空格是两个空格,所以就出现了我们看到的那样。


我们再修改下代码


#include <stdio.h>

#define SIZE (1 << 5)
int main()
{
 int x, y, i;
    printf("%d\n",SIZE);
    /*y用来控制列数*/
 for (y = SIZE - 1; y >= 0; y--,putchar('\n')) {
  /*控制行输出*/
        for (i = 0; i < y; i++) {putchar(' ');}
            for (x = 0; x + y < SIZE; x++){
                printf((x & y) ? "  " : "* ");
            }
 }
 return 0;
}


代码输出


weiqifa@bsp-ubuntu1804:~/c$ gcc shengdanshu.c && ./a.out
32
                               *
                              * *
                             *   *
                            * * * *
                           *       *
                          * *     * *
                         *   *   *   *
                        * * * * * * * *
                       *               *
                      * *             * *
                     *   *           *   *
                    * * * *         * * * *
                   *       *       *       *
                  * *     * *     * *     * *
                 *   *   *   *   *   *   *   *
                * * * * * * * * * * * * * * * *
               *                               *
              * *                             * *
             *   *                           *   *
            * * * *                         * * * *
           *       *                       *       *
          * *     * *                     * *     * *
         *   *   *   *                   *   *   *   *
        * * * * * * * *                 * * * * * * * *
       *               *               *               *
      * *             * *             * *             * *
     *   *           *   *           *   *           *   *
    * * * *         * * * *         * * * *         * * * *
   *       *       *       *       *       *       *       *
  * *     * *     * *     * *     * *     * *     * *     * *
 *   *   *   *   *   *   *   *   *   *   *   *   *   *   *   *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
weiqifa@bsp-ubuntu1804:~/c$


这样看起来是不是很酷了。


我在我的另一个号里面用这样方法画了一个圣诞树,我觉得也挺有意思的,喜欢的同学可以看看,当时写那个代码的时候是圣诞夜,我们刚好在开会,觉得有点无聊。


链接如下


如何用 C 语言画一个「圣诞树」?


知乎上的大神画圣诞树,基础理论也是基于这个,后续剖析一下,我觉得非常有意思。


附上几张谢宾斯基三角形的图片

c语言画谢宾斯基三角形_C语言_03

c语言画谢宾斯基三角形_C语言_04

c语言画谢宾斯基三角形_C语言_05

c语言画谢宾斯基三角形_C语言_06

c语言画谢宾斯基三角形_C语言_07

c语言画谢宾斯基三角形_C语言_08

c语言画谢宾斯基三角形_C语言_09

c语言画谢宾斯基三角形_C语言_10

c语言画谢宾斯基三角形_C语言_11



参考:

[1]https://www.cnblogs.com/lfri/p/10128073.html

[2]https://codegolf.stackexchange.com/questions/6281/draw-a-sierpinski-triangle/6292#6292


推荐阅读:专辑|Linux文章汇总专辑|程序人生专辑|C语言我的知识小密圈