跳转到内容

分形/复平面迭代/Julia 集

来自维基教科书,开放的书籍,为开放的世界
   "... a single algorithm for computing all quadratic Julia sets does not exist."[1]



本书展示了如何为在动态平面中绘制集合编写不同的算法:Julia填充的 JuliaFatou 集,用于 复二次多项式。它分为两部分

  • 各种算法的描述[2]
  • 动态平面中各种集合可视化技术的描述
    • Julia 集
    • Fatou 集
      • 无限吸引盆 (开集)
      • 有限吸引子的吸引盆
各种类型的动力学需要各种算法

基于吸引速度的方法

[编辑 | 编辑源代码]

这里颜色与吸引速度 (收敛到吸引子) 成正比。这些方法用于 Fatou 集。


如何找到

  • 最低最优逃逸值 (IterationMax)?[3]
  • 逃逸半径[4]


无限吸引盆 = 填充的 Julia 集外部和发散方案 = 逃逸时间方法 (ETM)

[编辑 | 编辑源代码]

首先阅读 定义

这里计算复点 Z0正向迭代

这是一个计算最后迭代的函数,即第一个落在目标集中的迭代 (例如,离开以给定逃逸半径 ER 为中心的圆) 用于上述 复二次多项式 的迭代。这是一个迭代 (整数),对于它 (abs(Z)>ER) 成立。它也可以改进[5]

C 版本 (这里 ER2=ER*ER) 使用双精度浮点数 (没有复数类型数字)

 int GiveLastIteration(double Zx, double Zy, double Cx, double Cy, int IterationMax, int ER2)
 {
  double Zx2, Zy2; /* Zx2=Zx*Zx;  Zy2=Zy*Zy  */
  int i=0;
  Zx2=Zx*Zx;
  Zy2=Zy*Zy;
  while (i<IterationMax && (Zx2+Zy2<ER2) ) /* ER2=ER*ER */
  {
   Zy=2*Zx*Zy + Cy;
   Zx=Zx2-Zy2 +Cx;
   Zx2=Zx*Zx;
   Zy2=Zy*Zy;
   i+=1;
  }
  return i;
 }

带有来自 GSL 的复数类型的 C:[6]

#include <gsl/gsl_complex.h>
#include <gsl/gsl_complex_math.h>
#include <stdio.h>
// gcc -L/usr/lib -lgsl -lgslcblas -lm t.c 
// function fc(z) = z*z+c

gsl_complex f(gsl_complex z, gsl_complex c) {
  return gsl_complex_add(c, gsl_complex_mul(z,z));
}

int main () {
  gsl_complex c = gsl_complex_rect(0.123, 0.125);
  gsl_complex z = gsl_complex_rect(0.0, 0.0);
  int i;
  for (i = 0; i < 10; i++) {
    z = f(z, c);
    double zx = GSL_REAL(z);
    double zy = GSL_IMAG(z);
    printf("Real: %f4 Imag: %f4\n", zx, zy);
  }
  return 0;
}

C++ 版本:

 int GiveLastIteration(complex C,complex Z , int imax, int ER)
  {
   int i; // iteration number
   for(i=0;i<=imax-1;i++) // forward iteration
    {
      Z=Z*Z+C; // overloading of operators
      if(abs(Z)>ER) break;
    }
   return i;
 }
#include <complex> // C++ complex library

// bailout2 = bailout * bailout
// this function is based on function esctime from mndlbrot.cpp 
// from program mandel ver. 5.3 by Wolf Jung
// http://www.mndynamics.com/indexp.html

int escape_time(complex<double> Z, complex<double> C , int iter_max,  double bailout2)
{ 
  // z= x+ y*i   z0=0
  long double x =Z.real(), y =Z.imag(),  u ,  v ;
  int iter; // iteration
  for ( iter = 0; iter <= iter_max-1; iter++)
  { u = x*x; 
    v = y*y;
    if ( u + v <= bailout2 ) 
       { 
         y = 2 * x * y + C.imag();
         x = u - v + C.real(); 
       } // if
    else break;
  } // for 
  return iter;
} // escape_time

[7]

Delphi 版本 (使用用户定义的复数类型、cabs 和 f 函数)

function GiveLastIteration(z,c:Complex;ER:real;iMax:integer):integer;
  var i:integer;
  begin
  i:=0;
  while (cabs(z)<ER) and (i<iMax) do
    begin
      z:= f(z,c);
      inc(i);
    end;
  result := i;
end;

其中

type complex = record x, y: real; end;

function cabs(z:complex):real;
begin
  cabs:=sqrt(z.x*z.x+z.y*z.y)
end;

function f(z,c:complex):complex; // complex quadratic polynomial
  var tmp:complex;
begin
  tmp.x := (z.x*z.x) - (z.y*z.y) + c.x;
  tmp.y := 2*z.x*z.y + c.y ;
  result := tmp;

end;

没有明确定义复数的 Delphi 版本

function GiveLastIteration(zx0,zy0,cx,cy,ER2:extended;iMax:integer):integer;
  // iteration of z=zx+zy*i under fc(z)=z*z+c
  // where c=cx+cy*i
  // until abs(z)<ER  ( ER2=ER*ER )  or i>=iMax
  var i:integer;
      zx,zy,
      zx2,zy2:extended;
  begin
  zx:=zx0;
  zy:=zy0;
  zx2:=zx*zx;
  zy2:=zy*zy;

  i:=0;
  while (zx2+zy2<ER2) and (i<iMax) do
    begin
      zy:=2*zx*zy + cy;
      zx:=zx2-zy2 +cx;
      zx2:=zx*zx;
      zy2:=zy*zy;
      //
      inc(i);
    end;
  result := i;
end;

Euler 版本 由 R. Grothmann 编写 (略微更改:从 z^2-c 到 z^2+c) [8]

function iter (z,c,n=100) ...

h=z;
loop 1 to n;
h=h^2 + c;
if totalmax(abs(h))>1e20; m=#; break; endif;
end;
return {h,m};
endfunction

Lisp 版本

此版本使用复数。它使代码变短,但效率也很低。

((DEFUN GIVELASTITERATION (Z_0 _C IMAX ESCAPE_RADIUS) 
  (SETQ Z Z_0) 
  (SETQ I 0)
  (LOOP WHILE (AND (< I IMAX) (< (ABS Z) ESCAPE_RADIUS)) DO 
    (INCF I)
    (SETQ Z (+ (* Z Z) _C)))
   I)

Maxima 版本

/* easy to read but very slow version, uses complex type numbers */ 
GiveLastIteration(z,c):=
 block([i:0],
  while abs(z)<ER and i<iMax
     do (z:z*z + c,i:i+1),
  i)$
/* faster version, without use of complex type numbers,
   compare with c version, ER2=ER*ER */  
GiveLastIter(zx,zy,cx,cy,ER2,iMax):=
block(
 [i:0,zx2,zy2],
 zx2:zx*zx,
 zy2:zy*zy,
 while (zx2+zy2<ER2) and i<iMax do
 (	
  zy:2*zx*zy + cy,
  zx:zx2-zy2 +cx,
  zx2:zx*zx,
  zy2:zy*zy,
  i:i+1
 ),
 return(i)
);

布尔逃逸时间

[编辑 | 编辑源代码]

算法:对于动态平面 (z 平面) 的每个点 z,计算 z 的幅度大于逃逸半径的迭代次数 (最后迭代)。如果 last_iteration=max_iteration,则该点位于填充的 Julia 集中,否则它位于其补集 (无限的吸引盆) 中。这里有两个选项,因此它被称为布尔算法。

if (LastIteration==IterationMax)
   then color=BLACK;   /* bounded orbits = Filled-in Julia set */
   else color=WHITE;  /* unbounded orbits = exterior of Filled-in Julia set  */

理论上,该方法用于绘制 填充的 Julia 集 及其补集 (外部),但当 c 是 Misiurewicz 点 ( 填充的 Julia 集 没有内部) 时,该方法不会绘制任何东西。例如对于 c=i。这意味着它非常适合绘制 填充的 Julia 集 的内部。


ASCII 图形
[编辑 | 编辑源代码]
; common lisp
(loop for y from -2 to 2 by 0.05 do
      (loop for x from -2 to 2 by 0.025 do
		(let* ((z (complex x y))
                   	(c (complex -1 0))
                   	(iMax 20)
			(i 0))

		(loop  	while (< i iMax ) do 
			(setq z (+ (* z z) c))
			(incf i)
			(when (> (abs z) 2) (return i)))
			

           (if (= i iMax) (princ (code-char 42)) (princ (code-char 32)))))
      (format t "~%"))
带有光栅图形的 PPM 文件
[编辑 | 编辑源代码]
c= =-1+0.1*i 的填充的 Julia 集。图像和 C 源代码

整数逃逸时间 = 无限吸引盆的水平集 = 水平集方法 = LSM/J

[编辑 | 编辑源代码]

逃逸时间测量逃逸到无穷大的时间(无穷大是多项式的超吸引点)。时间以逃逸出给定半径圆圈所需的步数(迭代 = i)来衡量(ER = 逃逸半径)。

你可以看到一些东西

这里的水平集是具有相同逃逸时间的点集。以下是黑白版本中选择颜色的算法。

  if (LastIteration==IterationMax)
   then color=BLACK;   /* bounded orbits = Filled-in Julia set */
   else   /* unbounded orbits = exterior of Filled-in Julia set  */
        if ((LastIteration%2)==0) /* odd number */
           then color=BLACK; 
           else color=WHITE;


以下是 c 函数,它

  • 使用复数双精度类型
  • 计算 8 位颜色(灰度色调)
  • 检查逃逸和吸引测试
unsigned char ComputeColorOfLSM(complex double z){

 int nMax = 255;
  double cabsz;
  unsigned char iColor;
	
  int n;

  for (n=0; n < nMax; n++){ //forward iteration
	cabsz = cabs(z);
    	if (cabsz > ER) break; // esacping
    	if (cabsz< PixelWidth) break; // fails into finite attractor = interior
  			
   
     	z = z*z +c ; /* forward iteration : complex quadratic polynomial */ 
  }
  
  
  iColor = 255 - 255.0 * ((double) n)/20; // nMax or lower walues in denominator
  
  
  return iColor;
}



 "if a 2-variable function z = f(x,y) has non-extremal critical points, i.e. it has saddle points, then it's best if the contour z heights are chosen so that the saddle points are on a contour, so that the crossing contours appear visually."Alan Ableson


如何选择水平曲线穿过临界点(及其前像)的参数?

  • 选择参数 c 使其位于逃逸线上,那么临界值也将位于逃逸线上
  • 选择逃逸半径等于临界值的第 n 次迭代
// find such ER for LSM/J that level curves croses critical point and it's preimages ( only for disconnected Julia sets)
double GiveER(int i_Max){

	complex double z= 0.0; // criical point
	int i;
	 ; // critical point escapes very fast here. Higher valus gives infinity
	for (i=0; i< i_Max; ++i ){
		z=z*z +c; 
	 
	 }
	 
	 return cabs(z);
	
	
}

归一化迭代次数(真实逃逸时间或分数迭代或平滑迭代计数算法 (SICA))

[编辑 | 编辑源代码]

数学公式

Maxima 版本

GiveNormalizedIteration(z,c,E_R,i_Max):=
/* */
block(
 [i:0,r],
 while abs(z)<E_R and i<i_Max
   do (z:z*z + c,i:i+1),
 r:i-log2(log2(cabs(z))),
 return(float(r))
)$

在 Maxima 中,log(x) 是 x 的自然(以 e 为底)对数。要计算 log2,请使用

log2(x) := log(x) / log(2);

描述

逃逸时间水平曲线方法 = eLCM/J

[编辑 | 编辑源代码]

这些曲线是逃逸时间水平集的边界(eLSM/J)。它们可以使用以下方法绘制

  • 水平曲线的边缘检测(= 水平集的边界)。
    • 基于 M. Romera 等人的论文的算法[9]
    • 索贝尔滤波器
  • 绘制勒尼萨卡 = 曲线 ,参见 解释和源代码
  • 绘制圆圈 及其前像。参见 此图像、解释和源代码
  • Harold V. McIntosh 描述的方法[10]
/* Maxima code : draws lemniscates of Julia set */
c: 1*%i;
ER:2;
z:x+y*%i;
f[n](z) := if n=0 then z else (f[n-1](z)^2 + c);
load(implicit_plot); /* package by Andrej Vodopivec */ 
ip_grid:[100,100];
ip_grid_in:[15,15];
implicit_plot(makelist(abs(ev(f[n](z)))=ER,n,1,4),[x,-2.5,2.5],[y,-2.5,2.5]);


水平曲线的密度[11]

  "The spacing between level curves is a good way to estimate gradients: level curves that are close together represent areas of steeper descent/ascent." [12]


 "The density of the contour lines tells how steep is the slope of the terrain/function variation. When very close together it means f is varying rapidly (the elevation increase or decrease rapidly). When the curves are far from each other the variation is slower" [13]


如何控制水平曲线

  • 逃逸半径
  • 目标集的形状
  • 手动
    • 绘制等势线
    • 更改水平集(水平曲线是水平集的边界)

有限吸引子的吸引盆 = 填充的 Julia 集的内部

[编辑 | 编辑源代码]
  • 如何找到周期吸引子?
  • 到达吸引子需要多少迭代?
点之间的距离和迭代次数

填充的 Julia 集内部的组成部分(法图集)

[编辑 | 编辑源代码]
  • 使用有限颜色(调色板 = 编号颜色的列表)
  • 找到吸引循环的周期
  • 找到吸引循环的一个点
  • 计算点到达吸引子后的迭代次数
  • 组件的颜色 = 迭代 % 周期[14]
  • 使用 边缘检测 绘制 Julia 集

内部水平集

[编辑 | 编辑源代码]

参见

  • Wolf Jung 编写的 Mandel 程序的算法 0


如何选择 吸引陷阱 的大小,使水平曲线在临界点处交叉?

这取决于

  • 动态类型(超吸引/吸引、抛物线型、排斥型)
  • 周期(抛物线型情况下 的子周期)


  • 抛物线型情况下的花瓣
    • 对于周期 1 和 2:以抛物点为中心的圆形,抛物点位于圆形边界上
    • 对于更高的周期,以抛物点为中心的圆形扇区
  • 对于其他情况(除了排斥),它是以吸引子为中心的圆形半径


int local_setup(double cx){
	
	c = cx;
	zp = GiveFixed(c);
	
	switch ( DynamicType){
		case repelling: // no  interior = no attracting fixed point = only escaping points
				
			break;
		case attracting: 
			delta = sqrt(1.0 - 4.0* creal(c));  // delta is a distance between alfa and beta fixed points
			AR =  delta /20.0;
			
	  		break;
  			
		case superattracting: // cabs(zp - zcr_last ) < PixelWidth 
			AR = 30.0* PixelWidth * iWidth / 5000 ; // 
	  		break;
		
		case parabolic:
				// zcr_last < parabolic_trap_center < zp
				int i; /* nr of point of critical orbit */
  				complex double z = zcr;
  				for (i=1;i<IterMax ; ++i) 
    					{ z = f(z); }
  				zcr_last = z;
				//
				AR = (zp - zcr_last)/2.0;
				parabolic_trap_center = ( creal(zp) + creal(zcr_last))/ 2.0;
				break;
		default: 
	}
	
	
	
	
	
	AR2 = AR*AR;
	
	
	return 0;
}

// and print program info
fprintf (stdout, "DynamicType value is setup manually; Once can do it also numerically ( from multiplier of fixed point alfa or from some other properities)\n");
  		switch ( DynamicType){
		case repelling: 
				fprintf (stdout, "\tThere is only one Fatou basin: basin of infinity \n");
				fprintf (stdout, "\tthere is no interior = Julia set is disconnected \n");
				fprintf (stdout, "\tcritical point z=0 is repelling = attracted to infinity \n");
				break;
		case attracting: 
	  			fprintf (stdout, "\tbasin type is attracting \n");
	  			fprintf (stdout, "\tzcr_last =  %.16f \talfa fixed point zp = %.16f\n", creal (zcr_last), creal(zp));// 
	  			fprintf (stdout, "\tdelta =  %.16f is the distance between fixed points\n", delta);// 
	  			fprintf (stdout, "\tAtracting Radius AR is set manually  = %.16f = %f * PixelWidth = %f * ImageWidth \n", AR, AR / PixelWidth, AR /ImageWidth );
	  			break;
  			
		case superattracting: 
				fprintf (stdout, "\tbasin type is superattracting \n");
	  			fprintf (stdout, "\tzcr =  %.16f  = zp = %.16f\n", creal (zcr), creal(zp));// 
	  			fprintf (stdout, "\tAtracting Radius AR is set manually  = %.16f = %f *PixelWidth = %f *ImageWidth \n", AR, AR / PixelWidth, AR /ImageWidth);
	  			break;
		
		case parabolic:
				fprintf (stdout, "\tbasin type  is parabolic \n");
				fprintf (stdout, "\tzcr_last =  %.16f < parabolic_trap_center = %.16f < zp = %.16f\n", creal (zcr_last), creal (parabolic_trap_center), creal(zp));// 
				fprintf (stdout, "\tzp - zcr_last =  %.16f AR*2 = %.16f \t difference = %.16f\n", creal (zp - zcr_last), AR *2.0, creal (zp - zcr_last) -  AR *2.0);// 
				fprintf (stdout, "\tAtracting Radius AR is tuned  = (zp - zcr_last)/2 = %.16f = %f *PixelWidth = %f *ImageWidth \n", AR, AR / PixelWidth, AR /ImageWidth);
				fprintf (stdout, "\tparabolic_trap_center z =  %.16f %+.16f*i  \n", creal (parabolic_trap_center), cimag (parabolic_trap_center));// parabolic_trap_center
				break;
		default: 
	
	
	
	
	}


抛物盆地的步骤

  • 选择临界点位于内部的组件
  • 选择 陷阱


陷阱是一个圆盘

  • 临界点位于内部的组件内
  • 陷阱在其边界上具有抛物点
  • 陷阱的中心是临界轨道的最后一个点和不动点之间的中点
  • 陷阱的半径是不动点和临界轨道的最后一个点之间距离的一半

目标集的分解

[编辑 | 编辑源代码]

示例

二进制分解

[编辑 | 编辑源代码]

这里像素的颜色(Julia 集的外部)与最后一次迭代的虚部的符号成正比(cimag)= 径向边界位于二进角(显示二进角的外部射线)。

主循环与逃逸时间相同。

半径

  • 逃逸半径 (ER) 应该更大:ER = 200
  • 吸引半径 (AR)
    • 对于超吸引情况很小:AR = 像素宽度


换句话说,目标集被分解成 2 部分(二进制分解)

伪代码中的算法 (Im(Zn) = Zy)

if (LastIteration==IterationMax)
   then color=BLACK;   /* bounded orbits = Filled-in Julia set */
   else   /* unbounded orbits = exterior of Filled-in Julia set  */
        if (Zy>0) /* Zy=Im(Z) */
           then color=BLACK; 
           else color=WHITE;

描述


unsigned char ComputeColorOfBD (complex double z)
{

  double cabsz;


  int i;			// number of iteration
  for (i = 0; i < IterMax_LSM; ++i)
    {


	cabsz = cabs(z); // numerical speed up : cabs(zp-z) = cabs(z) because zp = zcr = 0	

      // 
       if ( cabsz > ER  ||  cabsz < AR ) // if z is inside target set ( orbit trap) 
       		{ 
       			if (cimag(z) > 0) // binary decomposition of target set
       				{  return 0;}
       				else {return 255; }
     
      
      		}
	 
     
	
      z = f(z);	

    }

  return iColorOfUnknown;


}


吸引情况用于 "场线" 着色方法由 Gertbuschmann

这些曲线

  • 是二元分解框的边界
  • 不是电势场线 = 外部射线


注释

  • 如果逃逸半径太低,那么二进制(或三进制等)分解射线将在迭代带上具有可见的不连续性。增加逃逸半径会使不连续性变小,但会改变纵横比
  • mrob 说 exp(pi) 是二进制分解的最佳逃逸半径,因为它使框具有正方形纵横比(可能在使用指数映射变换时更明显?)
目标集按内部角度旋转
[编辑 | 编辑源代码]
 // for MBD
 double t0 = 1.0 / 3.0; // period = 3

// Modified BD
unsigned char ComputeColorOfMBD (complex double z)
{

  double cabsz;
  double turn; 

  int i;			// number of iteration
  for (i = 0; i < IterMax_LSM; ++i)
    {


	cabsz = cabs(z); // numerical speed up : cabs2(zp-z) = cabs2(z) because zp = zcr = 0	

      //  if z is inside target set ( orbit trap) = exterior of circle with radius ER 
       if ( cabsz > ER  ) // exterior
       		{ 
       			if (creal(z) > 0) // binary decomposition of target set
       				{  return 0;}
       				else {return 255; }
     
      
      		}
      		
      	if ( cabsz  < AR ) // if z is inside target set ( orbit trap) = interior of circle with radius AR
      		{
      			turn = c_turn(z);
      			if (turn < t0 || turn > t0+0.5) // modified binary decomposition of target set
      				{  return 0;}
       				else {return 255; }
     
      		
      		}
	 
     
	
      z = f(z);	

    }

  return iColorOfUnknown;


}
迭代次数恒定
[编辑 | 编辑源代码]


这里 Julia 集的外部被分解成径向水平集。

这是因为主循环没有跳出测试,并且迭代次数(迭代最大值)是恒定的。

它创建了径向水平集。

另请参阅

  for (Iteration=0;Iteration<8;Iteration++)
 /* modified loop without checking of abs(zn) and low iteration max */
    {
    Zy=2*Zx*Zy + Cy;
    Zx=Zx2-Zy2 +Cx;
    Zx2=Zx*Zx;
    Zy2=Zy*Zy;
   };
  iTemp=((iYmax-iY-1)*iXmax+iX)*3;        
  /* --------------- compute  pixel color (24 bit = 3 bajts) */
 /* exterior of Filled-in Julia set  */
 /* binary decomposition  */
  if (Zy>0 ) 
   { 
    array[iTemp]=255; /* Red*/
    array[iTemp+1]=255;  /* Green */ 
    array[iTemp+2]=255;/* Blue */
  }
  if (Zy<0 )
   {
    array[iTemp]=0; /* Red*/
    array[iTemp+1]=0;  /* Green */ 
    array[iTemp+2]=0;/* Blue */    
  };

它也与莫比乌斯变换群的自同构函数有关 [17]

吸引域中的 BDM
[编辑 | 编辑源代码]

吸引域中的 BDM(通常是 Julia 集的内部)给出了(伪)场线

解释 由 Gert Buschmann


朝向无穷大的迭代的等势线
形式为 的迭代的场线。

在每个 Fatou 域(不是中性的)中,有两个相互垂直的线系:等势线(用于势函数或实数迭代次数)和场线

如果我们根据迭代次数(而不是实数迭代次数 ,如上一节所定义)对 Fatou 域进行着色,则迭代的带显示了等势线的路径。如果迭代趋于 ∞(就像通常迭代 的外部 Fatou 域中那样),我们可以很容易地显示场线的路径,即根据迭代序列中的最后一个点在x轴上方还是下方来改变颜色(第一张图片),但在这种情况下(更确切地说:当 Fatou 域是超吸引时),我们无法连贯地绘制场线 - 至少不能通过我们在这里描述的方法。在这种情况下,场线也称为外部射线

z为吸引 Fatou 域中的一个点。如果我们对z进行大量的迭代,迭代序列的终点是一个有限循环C,而 Fatou 域(根据定义)是迭代序列收敛于C的点的集合。场线从C的点以及迭代到C中的点的(无限多个)点发出。它们在 Julia 集中结束于非混沌点(即生成有限循环的点)。设r为循环C的阶数(其点的数量),设z*C中的一个点。我们有r 次复合),我们定义复数 α 为

如果C的点是,α 是r 个数 的乘积。实数 1/|α| 是循环的吸引力,我们假设循环既不中性也不超吸引,这意味着 1 < 1/|α| < ∞。点z* 的不动点,在这个点附近,映射 具有(与场线相关的)旋转的特征,旋转的角度为 α 的幅角 β(即)。

为了给 Fatou 域着色,我们选择了一个小的数字 ε,并设置迭代序列 时停止,我们根据数字k(或者如果我们希望平滑着色,则根据实际迭代次数)对点z 着色。如果我们从z* 选择一个由角度 θ 给出的方向,则从z* 以这个方向发出的场线由以下点z 组成:数 的幅角 ψ 满足以下条件:

如果我们在场线方向(远离循环)上通过一个迭代带,则迭代次数k增加 1,而数字 ψ 增加 β,因此数字 沿场线保持恒定。

场线中的图像对于形式为 的迭代

对 Fatou 域场线的着色意味着我们对场线对之间的空间进行着色:我们选择从 z* 发出的几个规则分布的方向,并在每个方向上选择两个围绕该方向的方向。由于场线对的两个场线可能不会在 Julia 集的同一点结束,因此我们着色的场线在它们通往 Julia 集的路上可以(无限地)分叉。我们可以根据到场线中心线的距离进行着色,并且可以将这种着色与通常的着色混合在一起。这种图片可以非常装饰性(第二张图片)。

一条着色的场线(两条场线之间的区域)被迭代带划分,这样一部分可以与单位正方形建立一一对应关系:一个坐标是(从)到其中一条边界场线的距离计算出来的,另一个坐标是(从)到边界迭代带的内侧距离计算出来的(这个数字是实迭代次数的非整数部分)。因此,我们可以将图片放入场线中(第三张图片)。




待办事项
[edit | edit source]
  • 将斜率添加到白色

斥点的逆迭代用于绘制 Julia 集

复势 - Boettcher 坐标

[edit | edit source]

此处查看描述

DEM/J

[edit | edit source]

该算法有两个版本

将它与 参数平面和 Mandelbrot 集的版本 : DEM/M 进行比较。它与 M 集外部距离估计相同,但使用对 Z 的导数而不是对 C 的导数。

收敛

[edit | edit source]

在这个算法中,检查同一个轨道上两个点的距离

轨道的平均离散速度

[edit | edit source]
轨道的平均离散速度 - 代码和描述

它在以下情况下使用 

柯西收敛算法 (CCA)

[edit | edit source]

该算法由用户:Georg-Johann 描述。这里还有 Paul Nylander 编写的 Matemathics 代码

正规性

[edit | edit source]

正规性 在此算法中,检查两个轨道上点的距离

Michael Becker 检查 等连续性

[edit | edit source]

"迭代在 Fatou 集 上是等连续的,而在 Julia 集 上则不是"。(Wolf Jung)[18][19]

Michael Becker 在黎曼球面上比较了迭代下两个靠近点的距离。[20][21]

此方法不仅可以用于绘制多项式的 Julia 集(其中无穷大始终是超吸引不动点),还可以应用于其他函数(映射),其中无穷大不是吸引不动点。[22]

使用 Wolf Jung 的 Marty 准则

[edit | edit source]

Wolf Jung 正在使用“一种检查正规性的替代方法,它基于 Marty 的准则:|f'| / (1 + |f|^2) 对于所有迭代必须有界”。它在 mndlbrot::marty 函数中实现(请参阅 程序 Mandel 版本 5.3 的源代码)。它使用动态平面上的一点。

科尼格斯坐标

[edit | edit source]

科尼格斯坐标 用于有限吸引(非超吸引)点(循环)的吸引盆中。

优化

[edit | edit source]

你不需要平方根来比较距离。[23]

Julia 集可以具有许多对称性 [24][25]

二次 Julia 集始终具有旋转对称性(180 度) 

colour(x,y) = colour(-x,-y)

当 c 位于实轴上(cy = 0)时,Julia 集也具有反射对称性:[26]

colour(x,y) = colour(x,-y)

算法 

  • 计算一半图像
  • 旋转并添加另一半
  • 将图像写入文件 [27]

目标集

[编辑 | 编辑源代码]

目标集

  • 前向轨道的陷阱
  • 它是一个集合,可以捕获任何趋于固定点/ 周期点 的轨道。

Julia 集

[编辑 | 编辑源代码]

"大多数用于计算 Julia 集的程序在基础动力学是双曲的时运行良好,但在抛物线情况下会遇到指数级减速。"(Mark Braverman)[28]

  • 当 Julia 集是不会在二次映射迭代下逃逸到无穷大的点集时(= 填充的 Julia 集没有内部 = dendrt)
    • IIM/J
    • DEM/J
    • 检查正态性
  • 当 Julia 集是两个吸引盆之间的边界时(= 填充的 Julia 集没有空的内部) 
    • 边界扫描 [29]
    • 边缘检测

Fatou 集

[编辑 | 编辑源代码]

填充的 Julia 集的内部可以被着色 

周期点

[编辑 | 编辑源代码]

更多内容请查看 这里

可以使用  制作视频

  • 放大动态平面
  • 沿参数平面内的路径更改参数 c [32]
  • 更改着色方案(例如颜色循环)

示例 

更多教程和代码

[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]
  1. Mark Braverman 和 Michael Yampolsky 的 Julia 集的可计算性
  2. 来自 Ultra Fractal 的标准着色算法
  3. 新分形论坛 : 曼德尔布罗集的最低最佳逃逸值/
  4. math.stackexchange 问题:多项式的逃逸半径及其填充的 Julia 集
  5. Bruce Dawson(Fractal eXtreme 的作者)的通过代数实现更快的分形
  6. 来自 tensorpudding 的使用 gsl 的 C 代码
  7. Wolf Jung 在 GNU 通用公共许可证 下的程序 Mandel
  8. R. Grothmann 的 Euler 示例
  9. 通过逃逸线方法绘制曼德尔布罗集。M. Romera 等人
  10. Julia 曲线,曼德尔布罗集,Harold V. McIntosh。
  11. PythonDataScienceHandbook:Jake VanderPlas 的密度和等高线图
  12. math.stackexchange 问题:等高线表示什么
  13. Rodolphe Vaillant 的等高线
  14. E Demidov 的不动点和周期轨道
  15. 视频 : bryceguy72 的 Julia 集与磁场线的变形
  16. 视频 : FreymanArt 的用色带/条纹变形 Julia 集
  17. Gerard Westendorp : 黎曼曲面的柏拉图式镶嵌 - 8 次迭代自同态函数 z->z^2 -0.1+ 0.75i
  18. Alan F. Beardon, S. Axler, F.W. Gehring, K.A. Ribet : 有理函数迭代:复分析动力系统。Springer,2000 年;ISBN 0387951512,9780387951515;第 49 页
  19. Joseph H. Silverman : 动力系统的算术。Springer,2007 年。 ISBN 0387699031,9780387699035;第 22 页
  20. Georg-Johann 可视化 Julia 集
  21. 问题 : 在迭代下,两个相近点的距离如何变化?如果我知道这一点,我能判断这些点属于哪个集合吗?
  22. Michael Becker 的 Julia 集。请查看度量 d(z,w)
  23. 算法 : wikibooks 中的距离近似
  24. Evgeny Demidov 的 Julia 集对称性
  25. mathoverflow : z2c 的 Julia 集对称性
  26. htJulia Jewels:Michael McGoodwin 对 Julia 集的探索 (2000 年 3 月)
  27. Jonas Lundgren 在 Matlab 中的 Julia 集
  28. Mark Braverman : 关于抛物线 Julia 集的有效计算
  29. 抛物线不动点情况下的 Julia 集计算机建模算法 N.B.Ampilova,E.Petrenko
  30. Keenan Crane 在 GPU 上的射线追踪四元数 Julia 集
  31. Tomoki Kawahira 对填充的 Julia 集内部的镶嵌
  32. devianart 上的 Julia 集动画
华夏公益教科书