in reply to Generating Fractals with Perl?
1)swig -perl5 fractal.i 2)gcc -fpic -c fractal_wrap.c mandel.c -Dbool=char -I/usr/lib +/perl5/5.6.0/i586-linux/CORE 3)gcc -shared fractal_wrap.o mandel.o -lgd -o Fractal.so 4)fractal.pl #fractal.i ############################################ %module Fractal %{ #include "mandel.h" %} %include "mandel.h" ############################################## #mandel.c ############################################# #include <math.h> #include <stdio.h> #include <gd.h> #include "mandel.h" typedef struct { double r, i; } complex; int draw_mandel (char *filename, int width, int height, double origin_real, double origin_imag, double range, double max_iterations) { complex origin; int colors[51], color, white, x, y, i; FILE *out; gdImagePtr im_out; origin.r = origin_real; /* Measured from top-left */ origin.i = origin_imag; if (!(out = fopen(filename, "wb"))) { fprintf(stderr, "File %s could not be opened\n"); return 1; } im_out = gdImageCreate(width, height); /* Create a canvas */ /* Allocate some gray colors. Start from black, and increment r,g,b values uniformly. This has the effect of varying the luminosity, while keeping the same hue. (Black = 0,0,0 and white = 255, 255,255 */ for (i = 0; i < 50; i++) { color = i * 4; colors[i] = gdImageColorAllocate(im_out, color,color,color); } white = gdImageColorAllocate(im_out, 255,255,255); /* For each pixel on the canvas do ... */ for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { complex z, c ; int iter; /* Convert the pixel to an equivalent complex number c, given the origin and the range. The range acts like an inverse zoom factor.*/ c.r = origin.r + (double) x / (double) width * range; c.i = origin.i - (double) y / (double) height * range; /* Examine each point calculated above to see if repeated substitutions into an equation like z(next) = z**z + c remains within a definite boundary. If after <max_iterations> iterations it still hasn't gone beyond the white area, it belongs to the Mandelbrot set. But if it does, we assign it a color depending on how far the series wants to jump out of bounds*/ color = white; z.r = z.i = 0.0; /* Starting point */ for (iter = 0; iter < max_iterations; iter++) { double dist, new_real, new_imag; /*calculate z = z^2 + c */ /* Recall that z^2 is a^2 - b^2 + 2abi, if z = a + bi, */ new_real = z.r * z.r - z.i * z.i + c.r; new_imag = 2 * z.r * z.i + c.i; z.r = new_real; z.i = new_imag; /* Pythagorean distance from 0,0 */ dist = new_real * new_real + new_imag * new_imag; if (dist >= 4) { /* No point on the mandelbrot set is more than 2 units away from the origin. If it quits the boundary, give that 'c' an interesting color depending on how far the series wants to jump out of its bounds */ color = colors[(int) dist % i]; break; } } gdImageSetPixel(im_out, x,y, color); } } gdImagePng(im_out,out); fclose(out); return 0; } ############################################ #mandel.h ######################################### extern int draw_mandel (char *filename, int width, int height, double origin_real, double origin_imag, double range, double max_iterations); ###################################### #fractal.pl ####################################### #!/usr/bin/perl use Fractal; Fractal::draw_mandel('mandel.png', 300, 300, -1.5, 1.0,2.0, 20); # ########### file , width, height, origin x,y max-iterations #########################################
|
|---|