如何编写分形图?

San*_*uys 77 theory fractals

我对编程分形没有任何经验.当然,我已经看过着名的Mandelbrot图像等.

你能为我提供简单的分形算法吗?

编程语言并不重要,但我最熟悉的是actionscript,C#,Java.

我知道,如果我谷歌分形,我得到了很多(复杂的)信息,但我想从一个简单的算法开始并使用它.

也欢迎提出改进基本算法的建议,比如如何用那些可爱的颜色制作它们.

abe*_*nky 58

编程Mandelbrot很简单.
我的快速脏代码在下面(不保证没有错误,但是一个好的大纲).

这是轮廓:Mandelbrot集完全位于复杂网格中,半径为2.

因此,首先扫描该矩形区域中的每个点.每个点代表一个复数(x + yi).迭代那个复数:

[new value] = [old-value]^2 + [original-value] 同时跟踪两件事:

1.)迭代次数

2.)[新值]距离原点的距离.

如果达到最大迭代次数,则表示已完成.如果与原点的距离大于2,则表示您已完成.

完成后,根据您完成的迭代次数为原始像素着色.然后转到下一个像素.

public void MBrot()
{
    float epsilon = 0.0001; // The step size across the X and Y axis
    float x;
    float y;
    int maxIterations = 10; // increasing this will give you a more detailed fractal
    int maxColors = 256; // Change as appropriate for your display.

    Complex Z;
    Complex C;
    int iterations;
    for(x=-2; x<=2; x+= epsilon)
    {
        for(y=-2; y<=2; y+= epsilon)
        {
            iterations = 0;
            C = new Complex(x, y);
            Z = new Complex(0,0);
            while(Complex.Abs(Z) < 2 && iterations < maxIterations)
            {
                Z = Z*Z + C;
                iterations++;
            }
            Screen.Plot(x,y, iterations % maxColors); //depending on the number of iterations, color a pixel.
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

遗漏的一些细节是:

1.)准确了解复数的平方是什么以及如何计算它.

2.)弄清楚如何将(-2,2)矩形区域转换为屏幕坐标.


Fed*_*oni 28

你应该从Mandelbrot集开始,并了解它究竟是什么.

它背后的想法相对简单.您从复杂变量的函数开始

f(z)= z ^ 2 + C.

其中z是复变量,C是复数常数.现在你从z = 0开始迭代它,即你计算z1 = f(0),z2 = f(z1),z3 = f(z2),依此类推.序列z1,z2,z3,...有的那些常数C的集合,即它没有变为无穷大,是Mandelbrot集合(维基百科页面上图中的黑色集合).

在实践中,要绘制Mandelbrot集,您应该:

  • 在复平面中选择一个矩形(例如,从点-2-2i到点2 + 2i).
  • 用适当的矩形网格点(例如,400x400点)覆盖矩形,这将点映射到显示器上的像素.
  • 对于每个点/像素,令C为该点,计算相应的迭代序列z1,z2,z3,...的20个项,并检查它是否"变为无穷大".在实践中,您可以在迭代时检查20个术语之一的绝对值是否大于2(如果其中一个术语确实存在,则后续术语保证无限制).如果有一些z_k,则序列"变为无穷大"; 否则,你可以认为它是有界的.
  • 如果对应于某个点C的序列是有界的,则将图片上的相应像素绘制成黑色(因为它属于Mandelbrot集).否则,请用另一种颜色绘制.如果你想获得乐趣并产生漂亮的情节,可以根据abs的大小(第20个术语)以不同的颜色绘制它.

关于分形的惊人事实是我们如何从容易且明显无害的要求中获得极其复杂的集合(特别是Mandelbrot集合的边界).

请享用!


lus*_*oog 10

如果复杂数字让您头疼,那么可以使用L系统制定各种各样的分形.这需要几层交互,但每个层本身都很有趣.

首先你需要一只乌龟.前进,后退,左,右,上笔,下笔.即使没有驱动它的L系统,使用乌龟几何体的龟图形也有很多有趣的形状.搜索"LOGO图形"或"海龟图形".完整的LOGO系统实际上是一个Lisp编程环境,使用了一个不带代表性的剑桥波兰语法.但你不必走得那么远,就可以使用乌龟概念获得一些漂亮的照片.

然后你需要一个层来执行L系统.L系统与Post-systemsSemi-Thue系统有关,与virii一样,它们跨越图灵完整性的边界.这个概念是字符串重写.它可以实现为宏扩展或带有额外控件的过程集来绑定递归.如果使用宏扩展(如下例所示),您仍然需要一个过程设置来将符号映射到turtle命令,以及迭代字符串或数组以运行编码的乌龟程序的过程.对于有界递归过程集(例如),您将turtle命令嵌入过程中,并将递归级别检查添加到每个过程或将其分解为处理函数.

这是一个使用宏扩展和一组非常简短的海龟命令的后记中的毕达哥拉斯树的例子.有关python和mathematica中的一些示例,请参阅我的代码高尔夫挑战.

ps l-system pythagoras tree luser-droog


Gre*_*ill 8

有一本名为Chaos and Fractals的好书在每一章末尾都有简单的示例代码,它实现了一些分形或其他例子.很久以前,当我阅读那本书时,我将每个示例程序(在某些基本方言中)转换为在网页上运行的Java小程序.小程序在这里:http://hewgill.com/chaos-and-fractals/

其中一个示例是简单的Mandelbrot实现.


abe*_*nky 6

另一个值得学习的优秀分形是Sierpinski Triangle Fractal.

基本上,绘制三角形的三个角(等边是优选的,但任何三角形都可以工作),然后在其中一个角上开始一个点P. 随意将P移动到三个角中的任意一个,并在那里画一个点.再次将P移向任意一个角落,画出并重复.

您认为随机运动会产生随机结果,但事实并非如此.

参考:http://en.wikipedia.org/wiki/Sierpinski_triangle

  • 这实际上是IFS的基础,可以将其视为您描述的方法的概括. (2认同)

Per*_*son 6

Sierpinski三角形和Koch曲线是特殊类型的火焰分形.火焰分形是一种非常通用的迭代函数系统,因为它使用非线性函数.

IFS的算法如下:

Start with a random point.

重复以下几次(至少一百万,取决于最终图像大小):

Apply one of N predefined transformations (matrix transformations or similar) to the point. An example would be that multiply each coordinate with 0.5. Plot the new point on the screen.

如果该点位于屏幕之外,则在屏幕内随机选择一个新点.

如果你想要漂亮的颜色,让颜色取决于最后使用的变换.


Dav*_*nov 5

我会从一些简单的东西开始,比如Koch Snowflake.这是一个简单的过程,一条线并转换它,然后递归地重复该过程,直到它看起来整洁.

一些超级简单的东西,比如取2个点(一条线)并添加第三个点(制作一个角),然后重复创建的每个新部分.

fractal(p0, p1){
    Pmid = midpoint(p0,p1) + moved some distance perpendicular to p0 or p1;
    fractal(p0,Pmid);
    fractal(Pmid, p1);
}
Run Code Online (Sandbox Code Playgroud)


Gab*_*njo 5

我认为您可能不会将分形视为一种算法或要编程的东西。分形是一个概念!这是重复的详细模式的数学概念。

因此,可以使用不同的方法以多种方式创建分形,如下图所示。

在此处输入图片说明

选择一种方法,然后研究如何实施。这四个示例是使用Marvin Framework实现的。源代码在这里可用


Joh*_*kel 5

这是我使用纯 JavaScript 和 HTML 为 Mandelbrot 分形编写的代码笔。

希望代码很容易理解。

最复杂的部分是缩放和平移坐标系。同样复杂的是制作彩虹调色板。

function mandel(x,y) {
  var a=0; var b=0;
  for (i = 0; i<250; ++i) {
    // Complex z = z^2 + c
    var t = a*a - b*b;
    b = 2*a*b;
    a = t;
    a = a + x;
    b = b + y;
    var m = a*a + b*b;
    if (m > 10)  return i;
  }
  return 250;
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述