Fractals/Computer graphic techniques/2D
Contents |
Intro [edit]
All tasks can be done using :
- own programs ( GUI or console )
- own programs and graphic libraries
- graphic programs like GIMP
- fractal programs like :
- fractint
- xaos
- mandel by Wolf Jung
One can use free graphic libraries :
Creating graphic [edit]
Here are 3 targets / tasks :
- graphic file ( saving/ loading image )
- memory array ( processing image )
- screen pixels ( displaying image )
Graphic file [edit]
Memory array [edit]
Image in memory is a matrix :
- A 24-bit color image is an (Width x Height x 3) matrix.
- Gray-level and black-and-white images are of size (Width x Height) .
The color depth of the image :
- 8-bit for gray
- 24 or 32-bit for color,
- 1-bit for black and white.
Screen pixels [edit]
glxinfo | grep OpenGL
glxinfo | grep "direct rendering"
DRI [edit]
Direct Rendering Infrastructure (DRI2)[9]
Color [edit]
Curve [edit]
Tracing [edit]
Tracing curve [10]
Curve rasterisation [edit]
Ray [edit]
Ray can be parametrised with radius ( r)
Closed curve [edit]
Closed curve () can be parametrized with angle ( t).
Edge detection [edit]
- Boundary scanning method for Julia set - BSM/J
- Boundary scanning method for Mandelbrot set - BSM/M
- edge detection in Matlab [11]
Sobel filter [edit]
Short introduction [edit]
Sobel filter G consist of 2 filters (masks):
- Gh for horizontal changes.
- Gv for vertical changes.
Sobel kernels [edit]
The Sobel kernel contains weights for each pixel from the 8-point neighbourhood of a tested pixel. These are 3x3 kernels.
There are 2 Sobel kernels, one for computing horizontal changes and other for computing vertical changes. Notice that a large horizontal change may indicate a vertical border, and a large vertical change may indicate a horizontal border. The x-coordinate is here defined as increasing in the "right"-direction, and the y-coordinate is defined as increasing in the "down"-direction.
The Sobel kernel for computing horizontal changes is:
The Sobel kernel for computing vertical changes is:
Note that :
- sum of weights of kernels are zero


- One kernel is simply the other rotated by 90 degrees [12]
- 3 weights in each kernal are zero
Pixel kernel [edit]
Pixel kernel A containing central pixel
with its 3x3 neghbourhood :
Other notations for pixel kernel :
where : [13]
unsigned char ul, // upper left unsigned char um, // upper middle unsigned char ur, // upper right unsigned char ml, // middle left unsigned char mm, // middle = central pixel unsigned char mr, // middle right unsigned char ll, // lower left unsigned char lm, // lower middle unsigned char lr, // lower right
In array notation it is :[14]
In geographic notation usede in cellular aotomats it is central pixel of Moore neighbourhood.
So central ( tested ) pixel is :
![A_5 = mm = A[x][y] \,](http://upload.wikimedia.org/math/a/1/f/a1f71254ad4b4ae08afba2132466bc8c.png)
Sobel filters [edit]
Compute sobel filters ( where
here denotes the 2-dimensional convolution operation not matrix multiplication ). It is a sum of products of pixel and its weghts :
Because 3 weights in each kernal are zero so there are only 6 products. [15]
short Gh = ur + 2*mr + lr - ul - 2*ml - ll; short Gv = ul + 2*um + ur - ll - 2*lm - lr;
Result [edit]
Result is computed (magnitude of gradient):
It is a color of tested pixel .
One can also approximate result by sum of 2 magnitudes :
which is much faster to compute.[16]
Algorithm [edit]
- choose pixel and its 3x3 neighberhood A
- compute sobel filter for horizontal Gh and vertical lines Gv
- compute sobel filter G
- compute color of pixel
Programming [edit]
Lets take array of 8-bit colors ( image) called data. To find borders in this image simply do :
for(iY=1;iY<iYmax-1;++iY){ for(iX=1;iX<iXmax-1;++iX){ Gv= - data[iY-1][iX-1] - 2*data[iY-1][iX] - data[iY-1][iX+1] + data[iY+1][iX-1] + 2*data[iY+1][iX] + data[iY+1][iX+1]; Gh= - data[iY+1][iX-1] + data[iY-1][iX+1] - 2*data[iY][iX-1] + 2*data[iY][iX+1] - data[iY-1][iX-1] + data[iY+1][iX+1]; G = sqrt(Gh*Gh + Gv*Gv); if (G==0) {edge[iY][iX]=255;} /* background */ else {edge[iY][iX]=0;} /* boundary */ } }
Note that here points on borders of array ( iY= 0 , iY = iYmax , iX=0, iX=iXmax) are skipped
Result is saved to another array called edge ( with the same size).
One can save edge array to file showing only borders, or merge 2 arrays :
for(iY=1;iY<iYmax-1;++iY){ for(iX=1;iX<iXmax-1;++iX){ if (edge[iY][iX]==0) data[iY][iX]=0;}}
to have new image with marked borders.
Above example is for 8-bit or indexed color. For higher bit colors "the formula is applied to all three color channels separately" ( from RoboRealm doc).
Other implementations :
- ImagMagic discussion : using a sobel operator - edge detection
- Sobel in c from GIMP code
- Cpp code by Aaron Brooks - Brent Bolton - Jason O'Kane
- rosettacode : Image convolution
- C and opencl by royger
- C++ by Glenn Fiedler
- Convolution and Deconvolution
- Sobel Edge Detector by R. Fisher, S. Perkins, A. Walker and E. Wolfart with examples in Java
- Qt and GDI+ versions of the Sobel edge detection algorithm by Ken Earle
- Qt and OpenCV
Problems [edit]
Edge position :
In ImageMagic as "you can see, the edge is added only to areas with a color gradient that is more than 50% white! I don't know if this is a bug or intentional, but it means that the edge in the above is located almost completely in the white parts of the original mask image. This fact can be extremely important when making use of the results of the "-edge" operator." [17]
The result is :
- doubling edges ; "if you are edge detecting an image containing an black outline, the "-edge" operator will 'twin' the black lines, producing a weird result."[18]
- lines are not meeting in good points
See also new operators from 6 version of Image Magic : EdgeIn and EdgeOut from Morphology [19]
Edge thickening [edit]
convert $tmp0 -convolve "1,1,1,1,1,1,1,1,1" -threshold 0 $outfile
Filling contour [edit]
Quality of image [edit]
Interval arithemthic [edit]
Antialiasing [edit]
- TechInfo -AntiAliasing by Michael Condron
- Fract ( Lisp code) by Yannick Gingras
- Spatial anti aliasing at wikipedia [28]
- fractalforums discussion : Antialiasing fractals - how best to do it? [29]
Supersampling [edit]
Other names :
- antigrain geometry
- Supersampling ( downsampling) [30]
- subpixel accuracy
Examples :
- Cpp code by User Geek3
// subpixels finished -> make arithmetic mean char pixel[3]; for (int c = 0; c < 3; c++) pixel[c] = (int)(255.0 * sum[c] / (subpix * subpix) + 0.5); fwrite(pixel, 1, 3, image_file); //pixel finished
- command line version of Aptus ( python and c code ) by Ned Batchelder [31] ( see aptuscmd.py ) is using a high-quality downsampling filter thru PIL function resize [32]
- Java code by Josef Jelinek [33]: supersampling with grid algorithm, computes 4 new points (corners), resulting color is an avarage of each color component :
//Created by Josef Jelinek // http://java.rubikscube.info/ Color c0 = color(dx, dy); // color of central point // computation of 4 new points for antialiasing if (antialias) { // computes 4 new points (corners) Color c1 = color(dx - 0.25 * r, dy - 0.25 * r); Color c2 = color(dx + 0.25 * r, dy - 0.25 * r); Color c3 = color(dx + 0.25 * r, dy + 0.25 * r); Color c4 = color(dx - 0.25 * r, dy + 0.25 * r); // resulting color; each component of color is an avarage of 5 values ( central point and 4 corners ) int red = (c0.getRed() + c1.getRed() + c2.getRed() + c3.getRed() + c4.getRed()) / 5; int green = (c0.getGreen() + c1.getGreen() + c2.getGreen() + c3.getGreen() + c4.getGreen()) / 5; int blue = (c0.getBlue() + c1.getBlue() + c2.getBlue() + c3.getBlue() + c4.getBlue()) / 5; color = new Color(red, green, blue); }
- one can make big image ( like 10 000 x 10 000 ) and convert/resize it ( downsize ). For example using ImageMagic :
convert big.ppm -resize 2000x2000 m.png.
Plane [edit]
Description [edit]
2D plane can be described by :
- corners ( 4 points )
- center and width
- center and magnification ("If you use the center, you can change the zoom level and the plot zooms in/out smoothly on the same center point. " Duncan C)
Standard description in Fractint, Ultra Fractal, ChaosPro and Fractal Explorer are corners. For example initial plane for Mandelbrot set is
Corners: X Y Top-l -2.5000000000000000 1.5000000000000000 Bot-r 1.5000000000000000 -1.5000000000000000 Ctr -0.5000000000000000 0.0000000000000000 Mag 6.66666667e-01 X-Mag-Factor 1.0000 Rotation 0.000 Skew 0.000
Display window of parameter plane has :
- a horizontal width of 4 (real)
- a vertical width (height) of 3 (imag)
- an aspect ratio (proportion) 4/3 ( also in pixels 640/480 so ther is no distorsion)
- center z=-0.5
For julia set/ dynamic plane has :
Corners: X Y Top-l -2.0000000000000000 1.5000000000000000 Bot-r 2.0000000000000000 -1.5000000000000000 Ctr 0.0000000000000000 0.0000000000000000 Mag 6.66666667e-01 X-Mag-Factor 1.0000 Rotation 0.000 Skew 0.000
Description from documentation of Fractint :
CORNERS=[xmin/xmax/ymin/ymax[/x3rd/y3rd]]
Example: corners=-0.739/-0.736/0.288/0.291
Begin with these coordinates as the range of x and y coordinates, rather than the default values of (for type=mandel) -2.0/2.0/-1.5/1.5. When you specify four values (the usual case), this defines a rectangle: x- coordinates are mapped to the screen, left to right, from xmin to xmax, y-coordinates are mapped to the screen, bottom to top, from ymin to ymax. Six parameters can be used to describe any rotated or stretched parallelogram: (xmin,ymax) are the coordinates used for the top-left corner of the screen, (xmax,ymin) for the bottom-right corner, and (x3rd,y3rd) for the bottom-left. Entering just "CORNERS=" tells Fractint to use this form (the default mode) rather than CENTER-MAG (see below) when saving parameters with the [B] command.
CENTER-MAG=[Xctr/Yctr/Mag[/Xmagfactor/Rotation/Skew]]
This is an alternative way to enter corners as a center point and a magnification that is popular with some fractal programs and publications. Entering just "CENTER-MAG=" tells Fractint to use this form rather than CORNERS (see above) when saving parameters with the [B] command. The [TAB] status display shows the "corners" in both forms. When you specify three values (the usual case), this defines a rectangle: (Xctr, Yctr) specifies the coordinates of the center of the image.
Mag indicates the amount of magnification to use. Initial value ( no zoom ) is 6.66666667e-01.
Six parameters can be used to describe any rotated or stretched parallelogram: Xmagfactor tells how many times bigger the x- magnification is than the y-magnification,
Rotation indicates how many degrees the image has been turned.
Skew tells how many degrees the image is leaning over. Positive angles will rotate and skew the image counter-clockwise.
Parameters can be saved to parmfile called fractint.par
Wolf Jung uses :
/* from mndlbrot.cpp by Wolf Jung (C) 201 These classes are part of Mandel 5.7, which is free software; you can redistribute and / or modify them under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. In short: there is no warranty of any kind; you must redistribute the source code as well */ void mndlbrot::startPlane(int sg, double &xmid, double &rewidth) const { if (sg > 0) { xmid = -0.5; rewidth = 1.6; } // parameter plane else { xmid = 0; rewidth = 2.0; } // dynamic plane
Orientation [edit]
Check orientation of the plane by marking first quadrant of Cartesian plane :
if (x>0 && y>0) Color=MaxColor-Color;
It should be in upper right position.
Zoom [edit]
Notation [edit]
If you want to zoom [34]
baseSize // constant value = extend in real and imaginary axis when zoomLevel is zero. zoomLevel // inital value = 0.0 zoomFactor = 2^(-zoomLevel) // initial value = 1.0 = no zoom sizeX = zoomFactor * baseSize sizeY = zoomFactor * baseSize minImaginary = centerY - sizeY/2 maxImaginary = centerY + sizeY/2
Note that base of zoom factor is important when one wants to optimize zooming by using previosly computed pixels.
Usually other notation is used :
baseSize // constant value = extend in real and imaginary axis when zoomLevel is zero. zoomLevel // inital value = 0.0 zoomFactor = 10^zoomLevel // initial value = 1.0 = no zoom sizeX = baseSize / zoomFactor sizeY = baseSize / zoomFactor minImaginary = centerY - sizeY/2 maxImaginary = centerY + sizeY/2
and max zoom factor is :
Maximal zoom is correlated with :
Examples :
Pixel size [edit]
Pixel size is size of pixel in world coordinate. For linear scale and same resolution on both axes :
iSize = iXmax - iXmin ; // width of image in pixels ( integer or screen ) coordinate ; pixels are numbered from iXmin to iXmax; image is rectangular fSize = CxMax-CxMin // width of image in world ( floating point ) coordinate PixelWidth = fWidth / iWidth PixelSize = PixelWidth //
| ZoomFactor | iSize | fSize | PixelSize |
|---|---|---|---|
| 1 = 1.0e0 | 1000 | 3.0 | 0,003 |
| 100 = 1.0e2 | 1000 | 0.03 | 0.00003 |
| 1000 = 1.0e3 | 1000 | 0.003 | 0.0000003 |
Optimisation [edit]
- "recursive algorithm to split the image up into blocks, and tests each block to see whether it lies inside a “black area”." by Michael Hogg[41]
- Poincaré half-plane metric for zoom animation
- A Simple Optimization of Fractal Animation by Wei-Yin Chen, You-Sheng Yang and Kun-Mao Liang
- optimizing zoom animations by Claude Heiland-Allen [42]
- reenigne blog : recursive subdivision
- Xaos - algorithm description
Precision [edit]
What precision do I need for zoom ?
Scanning [edit]
See :
- Fractint Drawing Methods[43]
- Fratal Witchcraft drawing methods by Steven Stoft[44]
- AlmondBread algorithms [45]
All the pixels [edit]
Scan the plane :
- all pixels ( plane is scaned pixel by pixel )
- the same pixel size
Here in Lisp
; common lisp. Here float values can be used, there is no mapping (loop for y from -1.5 to 1.5 by 0.1 do (loop for x from -2.5 to 0.5 by 0.05 do (princ (code-char 42))) ; print char (format t "~%")) ; new line
and in C
/* c */ /* screen coordinate = coordinate of pixels */ int iX, iY, iXmin=0, iXmax=1000, iYmin=0, iYmax=1000, iWidth=iXmax-iXmin+1, iHeight=iYmax-iYmin+1; /* world ( double) coordinate = parameter plane*/ const double ZxMin=-5; const double ZxMax=5; const double ZyMin=-5; const double ZyMax=5; /* */ double PixelWidth=(ZxMax-ZxMin)/iWidth; double PixelHeight=(ZyMax-ZyMin)/iHeight; double Zx, Zy, /* Z=Zx+Zy*i */ Z0x, Z0y, /* Z0 = Z0x + Z0y*i */ for(iY=0;iY<iYmax;++iY) { Z0y=ZyMin + iY*PixelHeight; /* mapping from screen to world; reverse Y axis */ if (fabs(Z0y)<PixelHeight/2) Z0y=0.0; /* Zy = 0 is a special value */ for(iX=0;iX<iXmax;++iX) { /* initial value of orbit Z0 */ Z0x=ZxMin + iX*PixelWidth; } }
Optimization [edit]
Optimisation is described here
References [edit]
- ↑ ImageMagick image processing libraries
- ↑ GEGL (Generic Graphics Library)
- ↑ http://openil.sourceforge.net/
- ↑ http://freeimage.sourceforge.net/
- ↑ GD Graphics Library
- ↑ graphics magick
- ↑ OpenCv
- ↑ OpenImageIO
- ↑ w:Direct Rendering Infrastructure (DRI)
- ↑ Curve sketching in wikipedia
- ↑ matrixlab - line-detection
- ↑ Sobel Edge Detector by R. Fisher, S. Perkins, A. Walker and E. Wolfart.
- ↑ NVIDIA Forums , CUDA GPU Computing discussion by kr1_karin
- ↑ Sobel Edge by RoboRealm
- ↑ forum nvidia : Sobel Filter Don't understand a little thing in the SDK example
- ↑ Sobel Edge Detector by R. Fisher, S. Perkins, A. Walker and E. Wolfart.
- ↑ Image Magic doc
- ↑ Edge operator from Imagew Magic dosc
- ↑ imagemagick doc : morphology / edgein
- ↑ dilation at HIPR2 by Robert Fisher, Simon Perkins, Ashley Walker, Erik Wolfart
- ↑ imagemagick doc : morphology, dilate
- ↑ Fred's ImageMagick Scripts
- ↑ ON THE NUMERICAL CONSTRUCTION OF HYPERBOLIC STRUCTURES FOR COMPLEX DYNAMICAL SYSTEMS by Jennifer Suzanne Lynch Hruska
- ↑ "Images of Julia sets that you can trust" by Luiz Henrique de Figueiredo and Joao Batista Oliveira
- ↑ adaptive algorithms for generating guaranteed images of Julia sets by Luiz Henrique de Figueiredo
- ↑ Drawing Fractals With Interval Arithmetic - Part 1 by Dr Rupert Rawnsley
- ↑ Drawing Fractals With Interval Arithmetic - Part 2 by Dr Rupert Rawnsley
- ↑ Spatial anti aliasing at wikipedia
- ↑ fractalforums discussion : Antialiasing fractals - how best to do it?
- ↑ Supersampling at wikipedia
- ↑ Aptus ( python and c code ) by Ned Batchelder
- ↑ Pil function resize
- ↑ Java code by Josef Jelinek
- ↑ stackoverflow : how-do-i-zoom-into-the-mandelbrot-set
- ↑ video Mandelbrot Zoom 999 on youtube by phaumann
- ↑ zooming with exteded precision in Delphi
- ↑ [- talk]
- ↑ stackoverflow : mandelbrot-set-reaches-to-its-limit-way-too-soon
- ↑ fractalforums : problem with zooming transform one view rect-to another
- ↑ fractalforums "basic-location-and-zoom-question
- ↑ michael hogg : fractalnet
- ↑ optimizing zoom animations by Claude Heiland-Allen
- ↑ Fractint Drawing Methods
- ↑ Synchronous-Orbit Algorithm by R Munafo
- ↑ The Almond BreadHomepage by Michael R. Ganss




![\mathbf{A} =
\begin{bmatrix}
A[x-1][y+1] & A[x][y+1] & A[x+1][y+1] \\
A[x-1][y] & A[x][y] & A[x+1][y] \\
A[x-1][y-1] & A[x][y-1] & A[x+1][y-1]
\end{bmatrix}](http://upload.wikimedia.org/math/b/4/2/b429323afd28b37bc9c2d1b58fc40645.png)




