קובץ:Quadratic Golden Mean Siegel Disc Average Velocity - Gray.png

תוכן הדף אינו נתמך בשפות אחרות.
מתוך ויקיפדיה, האנציקלופדיה החופשית

לקובץ המקורי(1,500 × 1,100 פיקסלים, גודל הקובץ: 436 ק"ב, סוג MIME‏: image/png)

ויקישיתוף זהו קובץ שמקורו במיזם ויקישיתוף. תיאורו בדף תיאור הקובץ המקורי (בעברית) מוצג למטה.

תקציר

תיאור
English: Quadratic Golden Mean Siegel Disc with interior coloured by Average Velocity along orbit ( shades of gray )
תאריך יצירה
מקור נוצר על־ידי מעלה היצירה
יוצר Adam majewski

רישיון

אני, בעל זכויות היוצרים על עבודה זו, מפרסם בזאת את העבודה תחת הרישיון הבא:
w:he:Creative Commons
ייחוס שיתוף זהה
הקובץ הזה מתפרסם לפי תנאי רישיון קריאייטיב קומונז ייחוס-שיתוף זהה 3.0 לא מותאם.
הנכם רשאים:
  • לשתף – להעתיק, להפיץ ולהעביר את העבודה
  • לערבב בין עבודות – להתאים את העבודה
תחת התנאים הבאים:
  • ייחוס – יש לתת ייחוס הולם, לתת קישור לרישיון, ולציין אם נעשו שינויים. אפשר לעשות את זה בכל צורה סבירה, אבל לא בשום צורה שמשתמע ממנה שמעניק הרישיון תומך בך או בשימוש שלך.
  • שיתוף זהה – אם תיצרו רמיקס, תשנו, או תבנו על החומר, חובה עליכם להפיץ את התרומות שלך לפי תנאי רישיון זהה או תואם למקור.

Compare with

Images by Norbert Steinmetz from book "Rational Iteration. Complex Analytic Dynamical Systems" :

  • Fig 9 from page 86
  • Fig 8 from page 81[1]
  • firg without number from page 89[2]

תקציר

  • Julia set is drawn by
    • finding boundary between bounded and unbounded orbits using Sobel filter
    • DEM/J
  • Interior of filled JUlia set by average discrete velocity ( Chris King method)[3]

C src code

 
/*

  c console program
  It can be compiled and run under Linux, windows, Mac 
  It needs gcc

one can change :
- iSide ( width of image = iXmax = (15*iSide) it also changes IterationMax = (iXmax*50)
- distanceMax=PixelWidth*1; width of boundary ( JUlia set) is proportional to pixel width 
- NrOfCircles = 5; number of orbits inside Siegel Disc and its preimages; 
- method of coloring data[i]= 255 - ((int)(velocity*multiplier) % 255); color is proportional to velocity 

 

Based on Chris King algorithm and code 
[[:File:Golden_Mean_Quadratic_Siegel_Disc_Speed.png]]

  -----------------------------------------
  1.pgm file code is  based on the code of Claudio Rocchini
  http://en.wikipedia.org/wiki/Image:Color_complex_plot.jpg
  create 8 bit color graphic file ,  portable gray map file = pgm 
  see http://en.wikipedia.org/wiki/Portable_pixmap
  to see the file use external application ( graphic viewer)
  I think that creating graphic can't be simpler
  ---------------------------
  2. first it creates data array which is used to store color values of pixels,
  fills tha array with data and after that writes the data from array to pgm file.
  It alows free ( non sequential) access to "pixels"
  -------------------------------------------
Here are 4 items : 
1. complex plane Z with points z = zx+zy*i ( dynamic plane and world coordinate )
2. virtual 2D array indexed by iX and iYmax ( integer or screen coordinate )
3. memory 1D arrays data ( and edge) indexed by i =f(iX,iY)
4. pgm file 

  Adam Majewski   fraktal.republika.pl 
 
  
  to compile : 
  gcc v.c -lm -Wall 
  to run ( Linux console) :
  ./a.out

 
*/
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <string.h>

/* iXmax/iYmax = 11/15 */
const int iSide = 1000;
int iXmax ; /* width of image in pixels = (15*iSide); */
int iYmax ;
int iLength ;
/* */
const double ZxMin = -1.5;
const double ZxMax = 1.5;
const double ZyMin = -1.1;
const double ZyMax = 1.1;
/* (ZxMax-ZxMin)/(ZyMax-ZyMin)= iXmax/iYmax */

int IterationMax ; /* */

double PixelWidth ;
double PixelHeight ;

/* fc(z) = z*z + c */
/* Golden_Mean_Quadratic_Siegel_Disc */
const double Cx = -0.390540870218399; /* C = Cx + Cy*i */
const double Cy = -0.586787907346969;

/* radius of circle around origin; its complement is a target set for escaping points */
const double EscapeRadius = 2.0 ;
double ER2 ;

/* colors */
const unsigned int MaxColorComponentValue=255; /* color component is coded from 0 to 255 ; it is 8 bit color file */
const int iExterior = 245; /* exterior of Julia set */
const int iJulia = 0; /* border , boundary*/
const int iInterior = 230;

/* z fixed ( z=z^2 +c ) it is a center of Siegel Disc */
double zfx = -0.368684439039160, zfy= -0.337745147130762; 

double GiveDistanceFromCenter(double zx, double zy)
{double dx,dy;
 
 dx=zx-zfx;
 dy=zy-zfy;
 return sqrt(dx*dx+dy*dy);

} 

double GiveInternalSiegelDiscRadius()
{ /* compute critical orbit and finds smallest distance from fixed point */
  int i; /* iteration */
  double Zx=0.0, Zy=0.0; /* Z = Zx + Zy*i */
  double Zx2, Zy2; /* Zx2=Zx*Zx;  Zy2=Zy*Zy  */
   /* center of Siegel disc */
  
  double Distance;
  double MinDistance =2.0;  

  Zx2=Zx*Zx;
  Zy2=Zy*Zy;
  for (i=0;i<=400 ;i++)
    {
      Zy=2*Zx*Zy + Cy;
      Zx=Zx2-Zy2 +Cx;
      Zx2=Zx*Zx;
      Zy2=Zy*Zy;
      /* */
      
     Distance= GiveDistanceFromCenter(Zx,Zy);
     if (MinDistance>Distance) MinDistance=Distance; /* smallest distance */
    }
  return MinDistance;
}

/* escape time to infinity of function fc(z) = z*z + c */
int GiveExtLastIteration(double _Zx0, double _Zy0,double C_x, double C_y, int iMax, double _ER2, double SiegelRadius)
{ 
  int i; /* iteration */
  double Zx, Zy; /* Z = Zx + Zy*i */
  double Zx2, Zy2; /* Zx2=Zx*Zx;  Zy2=Zy*Zy  */
  

  Zx=_Zx0; /* initial value of orbit  */
  Zy=_Zy0;
  Zx2=Zx*Zx;
  Zy2=Zy*Zy;
  for (i=0;i<=iMax && ((Zx2+Zy2)<_ER2);i++)
    {
      Zy=2*Zx*Zy + C_y;
      Zx=Zx2-Zy2 +C_x;
      Zx2=Zx*Zx;
      Zy2=Zy*Zy;
      /* do not fall int infinite loop inside Siegel disc */
      if (GiveDistanceFromCenter(Zx,Zy)<=SiegelRadius) i=iMax;

     
    };
  return i; /* last iteration */
}

/* AverageVelocity along orbit =sum(dn)/n */
double GiveAverageVelocity(double _Zx0, double _Zy0,double C_x, double C_y, int iMax, double _ER2)
{ 
  int i; /* iteration */
  double pZx, pZy; /* pZ = Zx + Zy*i previous*/
  double nZx, nZy; /* next nZ = pZ*pZ + c */
  double Zx2, Zy2; /* Zx2=Zx*Zx;  Zy2=Zy*Zy  */
  double   sum=0.0;
  double dx,dy, distance=0.0; /* distance= sqrt(dx*dx+dy*dy); */

  pZx=_Zx0; /* initial value of orbit  */
  pZy=_Zy0;
  Zx2=pZx*pZx;
  Zy2=pZy*pZy;
  for (i=0;i<=iMax && ((Zx2+Zy2)<_ER2);i++)
    {
      nZy=2*pZx*pZy + C_y;
      nZx=Zx2-Zy2 + C_x;
      
      Zx2=nZx*nZx;
      Zy2=nZy*nZy;
      /* */
     dx=(nZx-pZx);
     dy=nZy-pZy;
     distance= sqrt(dx*dx+dy*dy);
     sum+=distance;
     /* */
     pZx=nZx;
     pZy=nZy;
     
    };
  return sum/i; /*  */
}

/*
 estimates distance from point c to nearest point in Julia  set 
 for Fc(z)= z*z + c
 z(n+1) = Fc(zn)  
 this function is based on function  mndlbrot::dist  from  mndlbrot.cpp
 from program mandel by Wolf Jung (GNU GPL )
 http://www.mndynamics.com/indexp.html 

Hyunsuk Kim : 
For Julia sets, z is the variable and c is a constant. Therefore df[n+1](z)/dz = 2*f[n]*f'[n] -- you don't add 1.

For the Mandelbrot set on the parameter plane, you start at z=0 and c becomes the variable. df[n+1](c)/dc = 2*f[n]*f'[n] + 1. 

 */
 double jdist(double Zx, double Zy, double Cx, double Cy ,  int iter_max)
 { 
 int i;
 double x = Zx, /* Z = x+y*i */
         y = Zy, 
         /* Zp = xp+yp*1 = 1  */
         xp = 1, 
         yp = 0, 
         /* temporary */
         nz,  
         nzp,
         /* a = abs(z) */
         a; 
 for (i = 1; i <= iter_max; i++)
  { /* first derivative   zp = 2*z*zp  = xp + yp*i; */
    nz = 2*(x*xp - y*yp) ; 
    yp = 2*(x*yp + y*xp); 
    xp = nz;
    /* z = z*z + c = x+y*i */
    nz = x*x - y*y + Cx; 
    y = 2*x*y + Cy; 
    x = nz; 
    /* */
    nz = x*x + y*y; 
    nzp = xp*xp + yp*yp;
    if (nzp > 1e60 || nz > 1e60) break;
  }
 a=sqrt(nz);
 /* distance = 2 * |Zn| * log|Zn| / |dZn| */
 return 2* a*log(a)/sqrt(nzp); 
 }

unsigned int f(unsigned int _iX, unsigned int _iY)
/* 
   gives position of point (iX,iY) in 1D array  ; uses also global variables 
   it does not check if index is good  so memory error is possible 
*/
{return (_iX + (iYmax-_iY-1)*iXmax );}

/* --------------------------------------------------------------------------------------------------------- */

int main(){

  
  
   /* sobel filter */
  unsigned char G, Gh, Gv; 
  
  
  /* */
  
  double velocity;
  const int NrOfCircles = 5; /* number of orbits inside Siegel Disc and its preimages;  */
  int multiplier = NrOfCircles * 2 * 255; /* it is used to find gray level ; value found by Trial and error method */
  
  
  
  unsigned int iX,iY; /* indices of 2D virtual array (image) = integer coordinate */
  iXmax = (15*iSide); /* height of image in pixels */
  iYmax = (11*iSide);
  iLength = (iXmax*iYmax);
  int LastIteration;
  IterationMax  = (iXmax*50);
  double Zx,Zy; 
  PixelWidth =  ((ZxMax-ZxMin)/iXmax);
  PixelHeight = ((ZyMax-ZyMin)/iYmax);
  double distance;
  double distanceMax=PixelWidth; /*  width of boundary is related with pixel width */
  ER2 = (EscapeRadius*EscapeRadius);
  

  /* dynamic 1D arrays for colors ( shades of gray ) */
  unsigned int i; /* index of 1D array  */
  unsigned char *data, *edge;
  data = malloc( iLength * sizeof(unsigned char) );
  edge = malloc( iLength * sizeof(unsigned char) );
  if (data == NULL || edge==NULL )
    {
      fprintf(stderr," Could not allocate memory");
      return 1;
    }
  else printf(" memory is OK\n");

  double SiegelRadius=GiveInternalSiegelDiscRadius();
  printf(" Siegel Internal Radius = %f \n",SiegelRadius );
  
  printf(" fill the data array \n");
  
  for(iY=0;iY<iYmax;++iY){ 
    Zy=ZyMin + iY*PixelHeight; /*  */
    if (fabs(Zy)<PixelHeight/2) Zy=0.0; /*  */
    printf(" row %u from %u \n",iY, iYmax);    
    for(iX=0;iX<iXmax;++iX){ 
      Zx=ZxMin + iX*PixelWidth;
      i= f(iX,iY); /* compute index of 1D array from indices of 2D array */
      LastIteration = GiveExtLastIteration(Zx, Zy, Cx, Cy, IterationMax, ER2, SiegelRadius );
      /* color of pixels */
      if ( LastIteration < IterationMax ) /* exterior  - unbounded orbits*/
           { 
             distance=jdist(Zx,Zy,Cx,Cy,IterationMax);
             if (distance<distanceMax) {
               data[i] = iJulia;
             edge[i] = iJulia; 
              }
             else {data[i] = iExterior;
                   edge[i] = iExterior; }
           } 
	
      else /* interior - bounded orbits */
      {velocity= GiveAverageVelocity(Zx,Zy,Cx,Cy,400,ER2); /* only 200 iterations !!!! */
      data[i]= 255 - ((int)(velocity*multiplier) % 255); /* color is proportional to velocity */
      edge[i] = iInterior;}
          
	 
      /* if (Zx>0 && Zy>0) data[i]=255-data[i];    check the orientation of Z-plane by marking first quadrant */
    }
  }

  

   printf(" find boundaries in edge array using Sobel filter and copy boundary to data array\n");   
  for(iY=1;iY<iYmax-1;++iY){ 
    for(iX=1;iX<iXmax-1;++iX){ 
      Gv= edge[f(iX-1,iY+1)] + 2*edge[f(iX,iY+1)] + edge[f(iX-1,iY+1)] - edge[f(iX-1,iY-1)] - 2*edge[f(iX-1,iY)] - edge[f(iX+1,iY-1)];
      Gh= edge[f(iX+1,iY+1)] + 2*edge[f(iX+1,iY)] + edge[f(iX-1,iY-1)] - edge[f(iX+1,iY-1)] - 2*edge[f(iX-1,iY)] - edge[f(iX-1,iY-1)];
      G = sqrt(Gh*Gh + Gv*Gv);
      i= f(iX,iY); /* compute index of 1D array from indices of 2D array */
      if (G!=0) {data[i]=iJulia;}  /* boundary */
    }
  }

 
  
   

  /* ---------- file  -------------------------------------*/
  printf(" save  data array to the pgm file \n");
  FILE * fp;
  char name [10]; /* name of file */
  i = sprintf(name,"r1IterationMax%u",IterationMax); /* result (is saved in i) but is not used */
  char *filename =strcat(name,".pgm");
  char *comment="# C= ";/* comment should start with # */
  /* save image to the pgm file  */      
  fp= fopen(filename,"wb"); /*create new file,give it a name and open it in binary mode  */
  fprintf(fp,"P5\n %s\n %u\n %u\n %u\n",comment,iXmax,iYmax,MaxColorComponentValue);  /*write header to the file*/
  fwrite(data,iLength,1,fp);  /*write image data bytes to the file in one step */
  printf("File %s saved. \n", filename);
  fclose(fp);

  /* --------------free memory ---------------------*/
  free(data);
  
  
  

  return 0;
}

References

  1. Siegel disc by Robert Steinmetz
  2. Siegel disc by Robert Steinmetz
  3. Combined Methods of Depicting Julia Sets by Chris King

כיתובים

נא להוסיף משפט שמסביר מה הקובץ מייצג

פריטים שמוצגים בקובץ הזה

מוצג

היסטוריית הקובץ

ניתן ללחוץ על תאריך/שעה כדי לראות את הקובץ כפי שנראה באותו זמן.

תאריך/שעהתמונה ממוזערתממדיםמשתמשהערה
נוכחית20:35, 11 בנובמבר 2011תמונה ממוזערת לגרסה מ־20:35, 11 בנובמבר 2011‪1,100 × 1,500‬ (436 ק"ב)Soul windsurfer

אין בוויקיפדיה דפים המשתמשים בקובץ זה.

שימוש גלובלי בקובץ

אתרי הוויקי השונים הבאים משתמשים בקובץ זה:

מטא־נתונים