Advanced fractal program skills-Chapter 1 to Chapter 4
Housisong@gmail.com
Abstract:
This series of articles is an introductory tutorial for fragment programmers. The chapters of this Article include (which may be added or deleted during planning ):
I. A set of Mandelbrot iterations; II. A simple periodic algorithm with smooth color; iii. Color smoothing of the number of iterations and escape interpolation;
4. Use the sin function for color smoothing; 5. A more effective formula for calculating the number of iterations to escape; 6. Use error diffusion to eliminate chromatic aberration;
7. color in the Set; 8. Julia set; 9. interpolation of the complex values generated by iteration;
10. High-order interpolation of the complex values generated by iteration; 11. Enlargement and rotation of the image; 12. Transformation of the plural initial values;
13. Fixed color table; 14. Design Pattern ing; 15. Texture ing; 16. Parallel Computing;
17. More iterative equations and color schemes; 18. Higher Order Mandelbrot sets; 19. Introduction of other fragges and fragment Animation
Body:
(Chapter 1-4 complete project source code: http://cid-10fa89dec380323f.office.live.com/self.aspx/.Public/hssFractal1%5E_4.zip
)
(My other fractal related articles: http://blog.csdn.net/housisong/category/382024.aspx
)
I. Set of Mandelbrot for multiple iterations
For the plural function f (z) = Z ^ 2 + z0; given any z0, the iteration can get the sequence: z0 ^ 2 + z0,
Z0 ^ 4 + 2 * z0 ^ 3 + z0 ^ 2 + z0,... we define z0 that is not divergent after any iteration
Mandelbrot set; rewrite the complex number equation to the corresponding real number equation:
X (I + 1) = x (I) * X (I)-y (I) * Y (I) + x (0); // real part
Y (I + 1) = x (I) * Y (I) * 2 + Y (0); // virtual part
Mandelbrot iteration function: After max_iter is iterated for a certain number of times, vertices without escape belong to the set and max_iter is returned;
If an escape occurs, the current number of iterations is returned. The Code is as follows: (when | z (I) | ^ 2> = 4, points inevitably escape)
Inline long mandelbrot1 (const double x0, const double y0, const long max_iter) {<br/> double X = x0; <br/> Double Y = y0; <br/> long I = 0; <br/> for (; I <max_iter; ++ I) {<br/> If (x * x + y * Y> = 4) <br/> break; <br/> double TMP = x * x-y * Y + x0; <br/> Y = x * y * 2 + y0; <br/> X = TMP; <br/>}< br/> return I; <br/>}
The number of iterations is mapped to the color value. A corresponding RGB color value is generated based on the number of escapes. The Code is as follows:
// Color = I % 256 <br/> // <br/> /////// <br/> inline color32 coloring1 (const long ITER, const long max_iter) {<br/> If (iter = max_iter) {<br/> return color32 (255, 0, 0 ); <br/>} else {<br/> return color32 (ITER * 20) % 256, (ITER * 15 + 85) % 256, (ITER * 30 + 171) % 256); <br/>}< br/>}
We uniformly sample with (width) * Height (height) points in the complex area of the 2 * r width of the center horizontal axis with points (x0, y0) as the center,
Obtain the number of iterations of the Mandelbrot and map it to a with (width) * Height (height) image. The Code is as follows:
Struct tviewrect {<br/> double x0, y0, R; <br/>}; <br/> void draw_mandelbrot1 (const tpixels32ref & DST, const tviewrect & rect, const long max_iter) {<br/> for (long y = 0; y <DST. height; ++ y) {<br/> for (long x = 0; x <DST. width; ++ X) {<br/> double X0 = (2 * rect. r) * x/DST. width + rect. x0-rect.r; <br/> double yr = rect. R * DST. height/DST. width; // y axis radius <br/> double Y0 = (2 * yr) * Y/DST. height + rect. y0-yr; <br/> long iter = mandelbrot1 (x0, y0, max_iter); <br/> DST. pixels (x, y) = coloring1 (ITER, max_iter); <br/>}< br/>
Call this function to generate an image. The Code is as follows: (size: 640x480, center (-0.5, 0), r = 2; Maximum number of iterations: 1000)
Const long max_iter = 1000; <br/> tviewrect rect; <br/> rect. x0 =-0.5; <br/> rect. y0 = 0; <br/> rect. R = 2; <br/> tpixels32 dstpic; <br/> dstpic. resizefast (640,480); <br/> draw_mandelbrot1 (dstpic. getref (), rect, max_iter); <br/>{// save PIC <br/> tfileoutputstream bmpoutstream (dstfilename); tbmpfile: Save (dstpic. getref (), & bmpoutstream); // Save the result image <br/>}
The generated image is as follows:
Ii. Simple period Algorithm for color Smoothing
Directly % the remainder can easily lead to a strong color ladder. We use a smooth function to process the conversion from iterative values to colors:
Color = (I % 510)-255; when I changes continuously, the color value is also continuously changed:
(Other codes are the same)
// Color = (I %510) -255 <br/> // <br/> /// <br/> // <br/> inline long modcolor2 (long ITER) {<br/> return ABS (ITER + 255) % 510-255); <br/>}< br/> inline color32 coloring2 (const long ITER, const long max_iter) {<br/> If (iter = max_iter) {<br/> return color32 (255, 0 ); <br/>} else {<br/> return color32 (modcolor2 (ITER * 20), modcolor2 (ITER * 15 + 85), modcolor2 (ITER * 30 + 171 )); <br/>}< br/>}
The generated image is as follows:
For the number of adjacent escape times, the current color is not smooth enough. You can remove the * multiplication coefficient to ensure that
(But the Color comparison is relatively small ):
Inline color32 coloring3_s (const long ITER, const long max_iter) {<br/> If (iter = max_iter) {<br/> return color32 (255,0, 0 ); <br/>} else {<br/> return color32 (modcolor2 (ITER), modcolor2 (ITER + 85), modcolor2 (ITER + 171 )); <br/>}< br/>}
The generated image is as follows:
3. Color smoothing of iterative escape Times Interpolation
The escape frequency difference between neighboring points is 1, which corresponds to 1/255 of the maximum brightness (for example, coloring1_s );
If we want to increase the color contrast between them, it is possible to produce a color gradient (for example, coloring1); how can we simultaneously meet
What are the two requirements? The answer is to interpolation the number of escape times!
Escape count
Interpolation Formula: I + 1-log (| z |)/log (p); (P is the exponent of the plural equation, here 2)
This is an approximate interpolation formula with certain errors. If multiple iterations are performed, the error of this formula can be reduced;
(Formula source see: http://linas.org/art-gallery/escape/ray.html)
The Code is as follows: (increases the number of iterations)
Static const double _ divlog2 = 1.0/log (2.0); <br/> inline double log2 (Double X) {<br/> return log (x) * _ divlog2; <br/>}< br/> inline double mandelbrot3 (const double x0, const double y0, const long max_iter) {<br/> double X = x0; <br/> Double Y = y0; <br/> long I = 0; <br/> for (; I <max_iter; ++ I) {<br/> If (x + y x> = 256) <br/> break; <br/> double TMP = x * x-y * Y + x0; <br/> Y = x * y * 2 + y0; <br/> X = TMP; <br/>}< br/> if (I! = Max_iter) {<br/> return I + 1-log2 (log2 (x * x + y * y); <br/>} else <br/> return I; <br/>}< br/> // color = (I % 510)-255 <br/> inline long modcolor3 (double ITER) {<br/> return (long) (ABS (fmod (ITER + 255,510)-255); <br/>}< br/> inline color32 coloring3 (const double ITER, const long max_iter) {<br/> If (iter = max_iter) {<br/> return color32 (255, 0 ); <br/>} else {<br/> return color32 (modcolor3 (ITER * 20), modcolor3 (ITER * 15 + 85), modcolor3 (ITER * 30 + 171 )); <br/>}< br/> void draw_mandelbrot3 (const tpixels32ref & DST, const tviewrect & rect, const long max_iter) {<br/> for (long y = 0; y <DST. height; ++ y) {<br/> for (long x = 0; x <DST. width; ++ X) {<br/> double X0 = (2 * rect. r) * x/DST. width + rect. x0-rect.r; <br/> double yr = rect. R * DST. height/DST. width; <br/> double Y0 = (2 * yr) * Y/DST. height + rect. y0-yr; <br/> double iter = mandelbrot3 (x0, y0, max_iter); <br/> DST. pixels (x, y) = coloring3 (ITER, max_iter); <br/>}< br/>}
The generated image is as follows:
4. Use the sin function for color Smoothing
The sin function is also a good color smoothing function. The function value is continuous and can be exported everywhere...
The generated color is softer. The Code is as follows:
// Color = sin (I) <br/> inline long sincolor (double ITER) {<br/> return (long) (sin (ITER * 2*3.1415926/510-3.1415926*0.5) + 1) * 0.5*255 ); <br/>}< br/> inline color32 coloring4 (const double ITER, const long max_iter) {<br/> If (iter = max_iter) {<br/> return color32 (255, 0, 0); <br/>} else {<br/> return color32 (sincolor (ITER * 20 ), sincolor (ITER * 15 + 85), sincolor (ITER * 30 + 171 )); <br/>}< br/> void draw_mandelbrot4 (const tpixels32ref & DST, const tviewrect & rect, const long max_iter) {<br/> for (long y = 0; y <DST. height; ++ y) {<br/> for (long x = 0; x <DST. width; ++ X) {<br/> double X0 = (2 * rect. r) * x/DST. width + rect. x0-rect.r; <br/> double yr = rect. R * DST. height/DST. width; <br/> double Y0 = (2 * yr) * Y/DST. height + rect. y0-yr; <br/> double iter = mandelbrot3 (x0, y0, max_iter); <br/> DST. pixels (x, y) = coloring4 (ITER, max_iter); <br/>}< br/>}
The generated image is as follows: