分形几何算法和实现,艺术引领数学

日期: 2019-11-29 20:48 浏览次数 :

绘画之于我,其实就是一种当下的体验和表达。

初识分形

1、分形的含义:

英文单词Fractal,它是由美籍法国数学家曼德勃罗(Benoit Mandelbrot)创造出来的。其含义是不规则的、破碎的、分数的。曼德勃罗是想用此词来描述自然界中传统欧几里得几何学所不能描述的一大类复杂无规的几何对象。

2、分形的几何特征:

自相似性:自相似,便是局部与整体的相似。

自仿射性:自仿射性是自相似性的一种拓展。如果,将自相似性看成是局部到整体在各个方向上的等比例变换的结果的话,那么,自仿射性就是局部到整体在不同方向上的不等比例变换的结果。前者称为自相似变换,后者称为自仿射变换。

精细结构:任意小局部总是包含细致的结构。

3、分形与计算机科学:

分形理论的发展离不开计算机图形学的支持,如果一个分形构造的表达,不用计算机的帮助是很难让人理解的。不仅如此,分形算法与现有计算机图形学的其他算法相结合,还会产生出非常美丽的图形,而且可以构造出复杂纹理和复杂形状,从而产生非常逼真的物质形态和视觉效果。

分形作为一种方法,在图形学领域主要是利用迭代、递归等技术来实现某一具体的分形构造。

分形几何学与计算机图形学相结合,将会产生一门新的学科——分形图形学。它的主要任务是以分形几何学为数学基础,构造非规则的几何图素,从而实现分形体的可视化,以及对自然景物的逼真模拟。

本文地址:

图片 1

图片 2

我的作品,常常会有人用不同的概念来界定、来评说,比如当代,比如传统等等。我想,对于绘画作品,每个人都会有不同的角度和理解以及表达方式,每个人的生活背景、经历、个体的体验都不尽相同,何必以某种形式来束缚自己的心灵和自由的表达呢!人们的创造性经常被专业化知识所主宰,植根于自然的灵性不断被人为的知识分割所消解,难以看到世界整体联系的纽带。在这个多种概念和方法相互冲击与混合为特征的时代,尤其如此。

分形图的递归算法

递归算法就不赘述了,凡是搞编程的应该都不陌生,可以参考我早前写过的一些递归程序题目小练一下:《递归练习(C语言)》

以Koch曲线的递归算法为例:

图片 3

代码如下:

#include<stdio.h>  #include<math.h>  #include<conio.h>  #include"graphics.h"  void  koch(double x0, double y0, double x1, double y1, int k)  {      double x2, y2, x3, y3, x4, y4;      x2 = 2.0/3 * x0 + 1.0/3 * x1;  /*由上面的运算可以得到其余三点 坐标的计算式*/      y2 = 2.0/3 * y0 + 1.0/3 * y1;      x3 = 1.0/3 * x0 + 2.0/3 * x1;      y3 = 1.0/3 * y0 + 2.0/3 * y1;      x4 = 1.0/2 * (x0 + x1) - sqrt(3.0)/6 * (y1 - y0);      y4 = 1.0/2 * (y0 + y1) + sqrt(3.0)/6 * (x1 - x0);      if( k > 1)    /*如果迭代次数大于1,就继续迭代下去,即执行以下程序*/      {          koch(x0, y0, x2, y2, k - 1);  /*对以(x0, y0)和(x2, y2)为端点的线段作为          初始线段进行迭代运算,以下类同*/          koch(x2, y2, x4, y4, k - 1);          koch(x4, y4, x3, y3, k - 1);          koch(x3, y3, x1, y1, k - 1);      } else {      /*如果迭代次数等于1,停止迭代,画出迭代生成的图形*/          line(x0, y0, x2, y2);       /*用直线联结两点(x0, y0)和(x2, y2)*/          line(x2, y2, x4, y4);       /*用直线联结两点(x2, y2)和(x4, y4)*/          line(x4, y4, x3, y3);       /*用直线联结两点(x4, y4)和(x3, y3)*/          line(x3, y3, x1, y1);       /*用直线联结两点(x3, y3)和(x1, y1)*/      }  }    int main()  {      int n, gdriver = DETECT, gmode;      /*定义迭代次数n*/      initgraph(&gdriver, &gmode,"C:\Win-TC\BGI");     /*图形系统初始化*/      printf("Please input the value of the positive integer n (n<9):");      scanf("%d", &n);               /*输入迭代次数n*/      setcolor(GREEN);      koch(50, 120, 450, 120, n);      getch();      closegraph(); /*关闭图形系统*/      return 0;  }

董大为2015年12月5日下午4点,董大为个展云的理论在空间站开幕。云的理论通过董大为不同系列的作品,试图构建一个他个人创作维度里具有一定宽度和代表性的作品谱系,这些作品体现出的多样性,如同物质世界里的生态链,是一个个完整的有机体。展览现场策展人郭芳认为,通常很多人把董大为的绘画归为抽象艺术,原因是他运用点、线、面、色块、构图等纯粹的基础绘画语言表现内心情感,放弃了具象的题材内容和情节。对于这一点,董大为说,其实他每件作品都有具象的母题,甚至他们同时看起来也是具象的。他甚至希望通过这种绘画回应一种错误的观念:抽象艺术没有确定的题材内容和共通的具象经验,因此无法与人共通。虽然这些具有多样面貌和众多可能的画面,究其根本都是由一个简单的点构成的,但这个构成的过程本身产生了张力。在开始准备这个展览之初,甚至在每个作品动笔之前,董大为就严格按照自己的计划完成作品,他一直很清楚要进行哪些系列,哪些题材,目的是希望呈现一个完整的展览,而非阶段性的作品展。展览现场卡尔维诺在创作小说《命运交叉的城堡》时,通过选择塔罗牌来构建小说的叙事结构。董大为的创作曾受此启发,他把每张画都想成是一张塔罗牌,试图让画中不同的墨点与结构、母题之间产生关联,比如当一个持花侍女在丛林中碰见一个佩剑武士就会发生一段奇异的故事一样。目前他画了8个系列:《波浪》,《涟漪》,《蛇》,《火山》,《断层》,《玫瑰》,《星球》和《理论云》。如果以此设想它们以一定的叙事结构关联在一起:比如想象一片有波浪的水域,水面突然分开,一条蛇从水面游过之后,逐渐恢复平静,波光粼粼的水波泛着点点涟漪;再比如,火山和断层,火山突然爆发,原因是地质内部发生地震。《断层》系列中的作品是最具有叙事性的,断层从两段变为三段再变为四段,意味着地震不断生发加强。董大为要求每张作品的尺寸都相同,就像一张张塔罗牌。为此他要克服许多障碍,因为技术的原因一些系列无法画成较大的尺幅,也只能因此而放弃,并对整个计划不断作出调整。展览现场在具象绘画领域,云是个例外,它是唯一没办法用透视理论表现的形象,但在数学的分形理论中,任何事物,包括自然界中最复杂的形状都可以由最基本的元素通过分形重复而获得,就连云都不例外。董大为的工作就是通过对基本元素结构的组合而完成的,这种方式不但可以构成抽象图形,也可以表现具象物体。并且,反过来看,每件作品在它看起来的样子背后,都有其特殊的结构方式。这种思维逻辑类似于数学和几何,往往通过简单有效的公式或模型表达特殊的规律和结构。展览现场虽然董大为的绘画理论基于数学思维,但是作品作为物质的载体,必须通过对特定材料的经验和把握,以及对特殊物理现象的设计才能顺利完成,这一转化过程要经历千百次的试验,所有的逻辑计算、试错实验、整合设计都被隐藏在简洁透明的画面之后。我们看到的部分如同一个科学家完成复杂证明之后,最终给予我们的公式或原理的模型化演绎。因此,相对于通常的抽象艺术,董大为的作品是有机的,实验性的,它们类似于分形几何学衍生出的分形信息、分形设计、分形艺术等视觉化的应用。云的理论是自然科学的思维模型,同时,董大为也确实画了一个系列叫理论云,但是那些由最基本的点构成的云的形状并非完全如科学般严谨规整,它还透露着艺术家无法藏匿的诗意和情感。展览现场

一般认为数学和艺术是不同的学科,一个致力于抽象概念,另一个则注重情感。但有时候两者的界限并不分明。

2012年对于我来说是个不平常的年份,在上苑艺术馆的驻馆,使我另起一行了。在这期间我对几何学中的分形理论以及中国传统绘画里的线有了进一步的理解和思考。分形几何是以非规则几何形态为研究对象,其概念是由曼德勃罗在上世纪60年代末提出来的。它的主要思想是说,在不规则现象表面所呈现的杂乱无章的背后仍存在着规律,这个规律就是在放大过程中呈现出的自相似性。基于传统欧几里得几何学的各门自然科学总是把研究对象想象成一个个规则的形体,而人类熟悉 却无法描述的自然界许许多多真实的图形竟如此不规则和支离破碎,与欧几里得几何图形相比,拥有完全不同层次的复杂性。

LS文法

LS文法先定义了绘图规则:

F:以当前方向前进一步,并画线;

f:以当前方向前进一步,不画线;

+:逆时针旋转角;

-:顺时针旋转角;

[:表示暂时保存当前的画图状态;

]:表示提取出保存的画图状态。 “[”和“]”要成对的出现。

Koch曲线的LS文法如下:

 w:F(初始字母)

 a :60(旋转角度)

 P:F → F + F - - F + F(F的替代文法)

根据这一文法生成Koch曲线的步骤(假设迭代两次):

第一步: 得到迭代两次的文法。

 第一次迭代结果:

             F + F - - F + F

 第二次迭代结果:(第一次迭代得到的结果的每一个F用规则P替换)

             F + F - - F + F + F + F - - F + F - - F + F - - F + F + F + F - - F + F

第二步:按照迭代得到的文法绘图。

当然,还有实现其他分形图的LS文法,这里就不一一举出了

下面的算法没有用递归,纯C语言实现:

/****************************************************  ** Completed on 2014.11.11 11:11  ** Programming environment:win xp + win-tc 2.0  ** Language: ANSI C  ** copyright(c)  codingwu   (Email: oskernel@126.com)  *****************************************************/  #include<stdio.h>  #include<stdlib.h>  #include<math.h>  #include<string.h>  #include<ctype.h>  #include<malloc.h>  #include<conio.h>  #include<graphics.h>    #define PI 3.1415926  #define stacksize 1024    typedef struct _point {      double x;      double y;      double delta;  }point;    typedef struct _L_Sys {      char *name;      char *startStr; /* 初始字符串 */      char *replaceF;      char *replaceX;  /* 替换X字符串 */      char *replaceY;  /* 替换Y字符串 */      char *replaceS;  /* 替换S字符串 */      char *replaceG;  /* 替换G字符串 */      char *replaceK;  /* 替换K字符串 */      char *replaceL;  /* 替换L字符串 */      char *replaceH;  /* 替换H字符串 */      int StartX;  /* 起始点坐标 */      int StartY;      int depth;   /* 递归深度 */      int ruleNumber;  /* 规则数 */      double angle;      double direct_init;      double length;    }L_Sys;    L_Sys ls[100];    void init_L_Sys(L_Sys *LS, char *_name, char *_startStr, char *_replaceF,          char *_replaceX, char *_replaceY, char *_replaceS, char *_replaceG,          char *_replaceK, char *_replaceL, char *_replaceH,  int _StartX,          int _StartY, int _depth, int _ruleNumber, double _angle,          double _direct_init, double _length)    /* 初始化 */  {      (*LS).name = (char *)malloc(strlen(_name) + 1);      if((*LS).name == NULL) return;      strcpy((*LS).name, _name);      (*LS).startStr = (char *)malloc(strlen(_startStr) + 1);      if((*LS).startStr == NULL) return;      strcpy((*LS).startStr, _startStr);      (*LS).replaceF = (char *)malloc(strlen(_replaceF) + 1);      if((*LS).replaceF == NULL) return;      strcpy((*LS).replaceF, _replaceF);      (*LS).replaceX = (char *)malloc(strlen(_replaceX) + 1);      if((*LS).replaceX == NULL) return;      strcpy((*LS).replaceX, _replaceX);      (*LS).replaceY = (char *)malloc(strlen(_replaceY) + 1);      if((*LS).replaceY == NULL) return;      strcpy((*LS).replaceY, _replaceY);      (*LS).replaceS = (char *)malloc(strlen(_replaceS) + 1);      if((*LS).replaceS == NULL) return;      strcpy((*LS).replaceS, _replaceS);      (*LS).replaceG = (char *)malloc(strlen(_replaceG) + 1);      if((*LS).replaceG == NULL) return;      strcpy((*LS).replaceG, _replaceG);      (*LS).replaceK = (char *)malloc(strlen(_replaceK) + 1);      if((*LS).replaceK == NULL) return;      strcpy((*LS).replaceK, _replaceK);      (*LS).replaceL = (char *)malloc(strlen(_replaceL) + 1);      if((*LS).replaceL == NULL) return;      strcpy((*LS).replaceL, _replaceL);      (*LS).replaceH = (char *)malloc(strlen(_replaceH) + 1);      if((*LS).replaceH == NULL) return;      strcpy((*LS).replaceH, _replaceH);      (*LS).StartX = _StartX;      (*LS).StartY = _StartY;      (*LS).depth = _depth;      (*LS).ruleNumber = _ruleNumber;      (*LS).angle = _angle;      (*LS).direct_init = _direct_init;      (*LS).length = _length;  }    void init(int n)  {   /*init_L_Sys(&ls[i], "hualei", "Start", "F", "X", "Y", "S", "G", "K", "L", "H",          pStartX, pStartY, depth, ruleNumber, angle, direct_init, length);          */      switch(n) {      case 0:          init_L_Sys(&ls[0], "xiecao", "G", "F-XF", "", "", "",              "GFX[+++++GFG][-----GFG]", "", "", "", 340, 20, 6, 2, -3, 60, 3.3);          break;      case 1:          init_L_Sys(&ls[1], "shusan", "X", "FF", "--FXF++FXF++FXF--", "", "",              "", "", "", "", 200, 50, 6, 2, -60, 0, 6);          break;      case 2:          init_L_Sys(&ls[2], "hualei", "F", "F[+F[+F][-F]F][-F[+F][-F]F]F[+F][-F]F",           "", "", "", "", "", "", "", 200, 20, 5, 1, 30, 90, 6);          break;      case 3:          init_L_Sys(&ls[3], "shuzhi", "K", "", "", "", "[+++G][---H]FFS",          "G+G[-FH]F", "FSF", "", "-H[+FG]F",          200, 210, 13, 4, -18, -90, 9.5);          break;      case 4:          init_L_Sys(&ls[4], "shuzhi", "F", "F[+F]F[-F]F", "", "", "",          "", "", "", "",          200, 5, 6, 1, -25.7341, 90, 1.5);          break;      case 5:          init_L_Sys(&ls[5], "korch", "F", "F[+F]F[-F]F", "", "", "",          "", "", "", "",          200, 5, 6, 1, -25.7341, 90, 1.5);          break;          case 6:          init_L_Sys(&ls[6], "pugongying", "Y", "", "X[-FFF][+FFF]FX",          "YFX[+Y][-Y]", "", "", "", "", "",          200, 10, 10, 2, 30, 90, 0.37);          break;          case 7:          init_L_Sys(&ls[7], "guanmucong", "F", "FF-[-F+F+F]+[+F-F-F]", "", "",           "", "", "", "", "",          250, 20, 6, 1, -30, 90, 3.5);          break;            case 8:          init_L_Sys(&ls[8], "kaihuadecao", "G", "", "XFX", "", "",          "[+FGF][-FGF]XG", "", "", "",          200, 10, 8, 2, -30, 90, 3);          break;      case 9:          init_L_Sys(&ls[9], "guanmucong2", "F",          "F[+++++++++++++++++++++++++F]-F[-------------------------F]F", "", "",          "", "", "", "", "",          370, 30, 6, 1, -1.2, 90, 2);          break;      case 10:          init_L_Sys(&ls[10], "yangliu", "F", "FF+[+F-F-F]-[-F+F+F]", "", "",          "", "", "", "", "", 170, 0, 5, 1, -22.5, 90, 7);          break;      case 11:          init_L_Sys(&ls[11], "Juliet", "X", "", "X+YF+", "-FX-Y", "", "", "", "", "",          95, 250, 17, 2, 90, 0, 1);      case 12:          init_L_Sys(&ls[12], "zhuanqiang", "X", "", "XFYFX+F+YFXFY-F-XFYF",           "YFXFY-F-XFYFX+F+YFXFY", "", "", "", "", "",          30, 40, 4, 2, 90, 0, 13);          break;      case 13:          init_L_Sys(&ls[13], "zhuanqiang_X", "F+F+F+F", "F+F-F-FF+F+F-F", "",           "", "", "", "", "", "",          80, 90, 4, 1, 90, 0, 3.5);          break;      case 14:          init_L_Sys(&ls[14], "sanjiaoraosanjiao", "X", "FFF", "--FXF++FXF++FXF--",           "", "", "", "", "", "",          200, 10, 6, 2, -60, 0, 1.7);          break;      case 15:          init_L_Sys(&ls[15], "yibimigong", "X", "", "-YF+XFX+FY-", "+XF-YFY-FX+",           "", "", "", "", "",          50, 30, 6, 2, -90, 0, 10);      case 16:          init_L_Sys(&ls[16], "shu", "X", "FF", "F[+X]F[-X]+X", "", "", "", "", "", "",          200, 10, 10, 2, 30, 90, 0.35);      case 17:          init_L_Sys(&ls[17], "duichengdeshu", "X", "FF", "F[+X][-X]FX", "", "",          "", "", "", "",          200, 10, 10, 2, 30, 90, 0.35);          break;      default:          break;      }      return;    }    void freeMemory(L_Sys *LS)  /* 释放内存 */  {      free((*LS).name);      (*LS).name = NULL;      free((*LS).startStr);      (*LS).startStr = NULL;      free((*LS).replaceF);      (*LS).replaceF = NULL;      free((*LS).replaceX);      (*LS).replaceX = NULL;      free((*LS).replaceY);      (*LS).replaceY = NULL;      free((*LS).replaceS);      (*LS).replaceS = NULL;      free((*LS).replaceG);      (*LS).replaceG = NULL;      free((*LS).replaceK);      (*LS).replaceK = NULL;      free((*LS).replaceL);      (*LS).replaceL = NULL;      free((*LS).replaceH);      (*LS).replaceH = NULL;  }    void fileCopy(FILE *dest, FILE *src) /* 复制文件函数 */  {      char ch;      fseek(src, 0, SEEK_SET);      ch = fgetc(src);      while(ch != EOF) {          fputc(ch, dest);          ch = fgetc(src);      }  }    void fractal(int curr_string)  /* 核心功能函数 */  {      int i, j, k, size, depth, len;      char a[2], ch;      double Delta;      FILE *result, *tmp;      point stack[stacksize];      point *p;      point bef, aft;        tmp = fopen("B.txt","w+");      if(tmp == NULL) return;      init(curr_string);      p = stack;      fputs(ls[curr_string].startStr, tmp);      depth = ls[curr_string].depth;      len =  ls[curr_string].length;      for(i = 0; i < depth; i++) {          result = fopen("A.txt","w+");          if(result == NULL) return;            fseek(tmp, 0, SEEK_SET);          ch = fgetc(tmp);          while(ch != EOF) {      /* F X Y S G K L H*/              if(ch == 'F') {                  fputs(ls[curr_string].replaceF, result);              } else if (ch == 'X') {                  fputs(ls[curr_string].replaceX, result);              } else if (ch == 'Y') {                  fputs(ls[curr_string].replaceY, result);              } else if (ch == 'S') {                  fputs(ls[curr_string].replaceS, result);              } else if (ch == 'G') {                  fputs(ls[curr_string].replaceG, result);              } else if (ch == 'K') {                  fputs(ls[curr_string].replaceK, result);              } else if (ch == 'L') {                  fputs(ls[curr_string].replaceL, result);              } else if (ch == 'H') {                  fputs(ls[curr_string].replaceH, result);              } else {                  fputc(ch, result);              }              ch = fgetc(tmp);          }         fseek(tmp, 0, SEEK_SET);         fileCopy(tmp, result);         fclose(result);      }      bef.x = ls[curr_string].StartX;      bef.y = ls[curr_string].StartY;        bef.delta = PI * (ls[curr_string].angle)/180;      Delta = PI * (ls[curr_string].angle)/180;   /* 转换为弧度制 */        result = fopen("A.txt","r");      fseek(result, 0, SEEK_SET);      ch = fgetc(result);      while(ch != EOF) {            switch(ch) {          case 'F':          case 'X':          case 'Y':          case 'S':          case 'G':          case 'K':          case 'L':          case 'H':              aft.x = bef.x + len * cos(bef.delta);              aft.y = bef.y - len * sin(bef.delta);              aft.delta = bef.delta;              line(bef.x, 400 - bef.y, aft.x, 400 - aft.y);                bef.x = aft.x;              bef.y = aft.y;              bef.delta = aft.delta;              break;          case '+':              bef.delta += Delta;              break;          case '-':              bef.delta -= Delta;              break;          case '[':              *(p++) = bef;              break;          case ']':              bef = *(--p);              break;          default:              break;          }          ch = fgetc(result);      }      fclose(tmp);      fclose(result);      freeMemory(&ls[curr_string]);  }    int main(void)  {      char ch;      int n, gdriver = DETECT, gmode;      wu:      printf("xiecao:0  shusan:1  hualei:2  shuzhi1:3  shuzhi2:4n");   /* 说明 */      printf("korch:5  pugongying:6  guanmucong:7  kaihuadecao:8  guanmucong2:9n");      printf("yangliu:10  Juliet:11  zhuanqiang:12  zhuanqiang_X:13  sanjiaoraosanjiao:14n");      printf("yibimigong:15  shu:16  duichengdeshu:17n");      printf("guanmucong2:9n");      printf("continue?(Y/N)n");      ch = getchar();      if(ch == 'n' || ch == 'N')          return 0;      else {          printf("please input a non-negative number to choose which image you what to see(0 <= n <= 17 ): ");          scanf("%d", &n);            initgraph(&gdriver, &gmode,"C:\Win-TC\BGI");  /*图形系统初始化*/          setcolor(GREEN);  /* 设置画笔的颜色 */          fractal(n);          getch();          closegraph();  /*关闭图形系统*/          getchar();          goto wu;      }      return 0;  }

 


编辑:丁晓洁

从伊斯兰瓷砖到杰克逊波洛克的混乱图案,我们可以看到艺术与数学研究之间的明显的相似性。两种思考模式并不完全相同,但有意思的是,似乎经常其中一个预示了另一个。

世界是非线性的,分形无处不在,分形学科的诞生.使得我们重新审视这个世界。当人们用分形的观点,重新审视自然物时,视野顿时开阔了很多。从分形理论的视野上看,我的作品不论是重彩、淡彩,都力图通过线的自由走动营造画面的气韵,不追求事物的外在模拟和形似,而是以线的铺排充分表达出某种内在的风神。它营造的是一种个体体验的幻觉感,将人的想象、情感等诸多因素引向更为自由和宽泛的彼岸。

是不是有时候艺术会启发数学发现呢?没有简单的答案,但在某些例子中,看起来很可能是的。

在东方绘画里,线是感情的媒介,画家凭借线条表现对象的精神,传达主观的情感,线条运用从曹衣出水吴带当风到后来的十八描,特点是借物抒情。中国绘画的线是长于抒情的,笔的挥洒处,线的显现就是画家的个性、情感的外化。线条的表现力体现在两个方面一是线条本身的变化。由不同线型及用笔产生的线的粗细轻重、浓淡,刚柔,虚实、顿挫、转折等变化,一是由线在画面上的安排组织、疏密、长短、取舍、前后穿插等,表现结构、空间、层次、节奏韵律及装饰风格。这两方面的结合决定着线的整体表现力。如感觉和想象的造物,根据欧几里得几何学定义,两点之间的连接产生一条线。线,是点的运动的轨迹。它不是来自自然,源于物像,是非表现性的,无生命的,这不是我们需要的线。

在14世纪和15世纪,阿尔罕布拉宫是柏柏尔人君主的宫殿和寝宫。对很多游客而言,这几乎是地球上最接近天堂的所在了:诸多有喷泉的楼天庭院,四周是遮阴避雨的环廊。天花板上布满了模印的类似钟乳石的精美几何图案。而最精美的当属四周墙壁的多彩瓷砖上的装饰,令人眼花缭乱,沉醉于喜悦之中。这种几何图案类似于音乐,令人灵魂出窍,如闻天音,喜不自胜。

而分形几何所呈现的无穷玄机和美感引发人们去探索。即使你不懂得其中深奥的数学哲理,也会为之感动。分形几何使人们觉悟到科学与艺术的融合,数学与艺术审美上的统一,使昨日枯燥的数学不再仅仅是抽象的哲理,而是具体的感受;不再仅仅是揭示一类存在,而是一种艺术创作,分形搭起了科学与艺术的桥梁 。

阿尔汉布拉宫的瓷砖。Credit: 煎蛋第六位画师Chon

中国绘画是强调通过物化显示出哲学上的最高境界。也是以浑万象以冥观,兀同体乎自然来体验物化。它虽是哲学的境界,也是艺术的境界。正是在这一点上与分形理论有着天成的契合点。我坚信,在分形的思维中以线来体验、融通个体生命与博大的宇宙,以我之自然合物之自然,必然会充分地显示出强大的艺术创造力。

这是艺术的胜利,也是数学推理的胜利。这种装饰引发了一个数学分支名为铺砌问题,即利用规则的几何图形覆盖整个空间。数学上已证实,平面可被三角形、四边形和六边形等图形铺满,但五边形不行。

编辑:admin

结合不同的形状也是可以的,比如利用三角形、四边形和六边形瓷砖完全填充空间。阿尔罕布拉宫就浸淫于这种精美的几何组合,使得看起来似乎是在移动中,而不是静止。这些图案似乎在我们眼前旋转,令我们的脑子在观看的时候不断思考,不断排列、重新排列这些图案,形成不同的新图形(比如盯着厕所的瓷砖思考人生)。

情感体验?不错。但这种伊斯兰瓷砖最令人着迷的是这些无名艺术家和工匠的杰作还表现出几近完美的数理逻辑。数学家们已经鉴定出17种对称形:左右对称,旋转对称等等。阿尔罕布拉宫就包含了至少16种,就像是教科书的图解。

这些图案不仅仅是漂亮,还蕴含着严密的数学,几乎完全囊括了基本的对称特性。而数学家们直到阿尔罕布拉宫建成几个世纪之后才提出对称原理的分析。

准晶体瓷砖

虽然阿尔罕布拉宫的装饰物是极好的,但波斯的杰作可能还要更胜一筹。1453年,伊斯法罕Darbi-I Imam圣地的无名工匠发现了准晶体图形。这些图形具有复杂神秘的数学性质,直到1970年代彭罗斯拼图的发现,数学家才能够进行分析。

这种图形能以规则的形状完全填满空间,但是所用的图形绝不重复。实际上,即使趋近于无限也不会重复,不过黄金分割这一数学常数会不断重复出现。

Daniel Schectman由于发现了违反完形法则的准晶体获得2001年的诺贝尔奖。这一突破性进展迫使科学家重新考虑物质本质的概念。

2005年,哈佛物理学家Peter James Lu证实可以利用相对简单的结瓷砖(girih tile)产生准晶体图形。结瓷砖结合了几种纯粹的几何形状形成五种图案:正十边形,不规则的六边形,蝶形,菱形以及正五边形。

Girih tile. Credit: 煎蛋画师Chon

不管理论如何,反正Darbi-I Imam圣地的准晶体图案是由不精通数学的工匠制造的,花费了数学家几个世纪的功夫来分析和解释。换言之,直觉先于完全的理解。

透视与非欧几里得数学

几何透视使得画师能逼真而准确地描绘所见世界,引发了意大利文艺复兴的艺术变革。并且还可以说透视引起了对基础数学定律的重要重新检查。

根据欧几里得数学,两条平行线永远平行不相交。而在文艺复兴透视的世界中,平行直线在远处最终会相交于所谓的没影点。即是说,文艺复兴透视提出了一种遵循通常数学法则的几何,但是非欧几里得的。

Credit: 123RF

当数学家首次在19世纪早期提出非欧几里得数学时,他们想象出一个平行直线在无限远处相交的世界。他们所研究的几何在很多方面,都类似于文艺复兴透视图。

非欧几里得数学此后转向探索12维或者13维空间,远超文艺复兴的透视世界。但值得深思的是,文艺复兴艺术是否使得那最初的一步更为容易呢?

波洛克的混乱画作

现代艺术中一个有意思的个例打破了传统的界限,与近期的数学发展具有相似之处,那就是杰克逊波洛克的画作。

对于首次看到的人,波洛克的画作似乎非常混乱没有意义。但随着时间推移,我们会逐渐发现其中具有一定的有序元素,虽然并非传统意义上的那种。他们的形状既是可预测的,同时也是不可预测的,这种方式类似于水龙头的滴水,无从估计下一滴的准确效应。但是,如果我们绘制滴水的图案,就会发现会落入一个具有清晰形状和边界的区域。

这种不可预测性曾经超出了数学的处理能力。但近年来,这已成为最热门的数学探索领域之一。例如,混沌理论探索不可预测但落入确定可能性范围的模式,而分形分析研究类似但不相同的形状。

波洛克自己对数学没有任何特别的兴趣,而且已知对此领域并无多少天赋。他所创造出的这些迷人的形式都是出于直觉和主观。

有趣的是,数学家们至今仍未能准确描述波洛克在画作中所做的。例如,曾经有研究者试图利用分形分析创建他的风格的数值签名,但至今仍未能成功,无法区分波洛克的亲手画作与劣质的模仿。即使认为波洛克利用了分形的观点这一想法可能也是不正确的。

尽管如此,波洛克的同时混乱和有序的图形仍然为数学研究提供了多种可能方向。可能某一天,研究者能描述波洛克画作中的数学,艺术家也会继续前进,制定探索的新边界。

编辑:江兵