Visualizzazione post con etichetta PngWriter. Mostra tutti i post
Visualizzazione post con etichetta PngWriter. Mostra tutti i post

martedì 3 maggio 2016

Fixed point math e Mandelbrot

Un esempio di utilizzo della matematica a virgola fissa, un metodo di rappresentazione dei numeri reali con un numero prefissato di cifre decimali utilizzato in particolar modo per calcolatori privi di coprocessore matematico (per esempio il software Fractint usava questo tipo di approccio per il calcolo di frattali su processori 386 e 486 all'inizio degli anni 90)
Per effettuare un calcolo dell'insieme di Mandelbrot si puo' usare attualmente la libreria FIXEDPTC (Fixed Point Math Library for C)  (rispetto ad altre librerie, come FPMLib o LibFoixMath , e' possibile settare il proprio formato dati secondo le proprie necessita')

Visto che il calcolo e' tutto compreso per valori inferiori a 8 puo' essere utile, per massimizzare la precisione, usare una rappresentazione 4.28 (4 digit per la parte intera e 28 per la parte frazionaria) su un calcolatore a 32 bit. In questo modo il piu' piccolo numero calcolabile e' 0.00000000372529. Per la rappresentazione grafica e' stata usata la libreria PngWriter gia' usata qui
L'uso della libreria e' abbastanza autoesplicativo...l'unico aspetto un po' confuso e' che per effettuare dei confronti in un ciclo if...then si deve convertire il dato da formato a virgola fissa in float.

mand.c
------------------------------------------------------
#include <pngwriter.h>

#define FIXEDPT_WBITS 4
#define WIDTH 640
#define    HEIGHT 480

#include "fixedptc.h"

int main() {
int     j,k,i;
float    test;
fixedpt Re,Im,DRe,DIm;
fixedpt X,Y,DUE;
fixedpt XN,YN,YNN;
fixedpt    A,B;

pngwriter png(WIDTH,HEIGHT,0,"mandelbrot.png");

Re = fixedpt_rconst(-2.00390625); //finestra reale tra -2 e +0.5
Im = fixedpt_rconst(-1.205); //finestra immaginaria tra -1.2 e 1.2
DRe = fixedpt_rconst(0.00390625); //2.5/640
DIm = fixedpt_rconst(0.005); // 2.4/480
DUE = fixedpt_rconst(2.0);

A = Re;

for (j=0;j<WIDTH;j++)
    {
    A = fixedpt_add(A,DRe);
    B = Im;
    for (k=0;k<HEIGHT;k++)
    {
    B = fixedpt_add(B,DIm);

    X = fixedpt_rconst(0.0);
    Y = fixedpt_rconst(0.0);

    for (i=0;i<=255;i++)
        {
        XN=fixedpt_sub(fixedpt_mul(X,X),fixedpt_mul(Y,Y))+A; // (x*x) - (y*y) + A
        YN=fixedpt_mul(X,Y); // x*y
        YNN=fixedpt_mul(DUE,YN); // 2*x*y
        YN=YNN + B; // 2*x*y*+B
        test = fixedpt_tofloat(fixedpt_mul(XN,XN) + fixedpt_mul(YN,YN)); //(XN*XN)+(YN*YN)
        if (test > 4.0)
            {
            png.plot(j,k,1.0,1.0,1.0);
            break;
            }
        X = XN;
        Y = YN;
        }
    }
    }
png.close();

}

------------------------------------------------------

Per compilare il sorgente si puo' usare i seguenti comandi
------------------------------------------------------
rm mandelbrot.png
g++ mand.c -o mand  -I/usr/local/include  -L/usr/local/lib -lpng -lpngwriter
./mand
display mandelbrot.png

------------------------------------------------------

lunedì 17 settembre 2012

Esempio Mandelbrot con PngWriter/C

In questo esempio l'insieme di Mandelbrot e' stato generato con la libreria PngWriter che permette di creare dei file png.



La libreria e' gia' pacchettizzata in Debian ed e' di facile utilizzo perche' si deve solo indicare le dimensioni del file png da creare e le coordinate del punto da disegnare con il colore in formato RGB

Per compilare il file di esempio deve essere utilizzata la seguente stringa

g++ mand_png.c -o mand_png `freetype-config --cflags` -I/usr/local/include  -L/usr/local/lib -lpng -lpngwriter -lz -lfreetype

I file del progetto sono reperibili a questo Link


Per visualizzare il file png da linea di comando puo' essere utile installare il pacchetto ImageMagick e digitare

display mandelbrot.png

-------------------------------------------------

#include <pngwriter.h>

#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768

float re_min = -2.0;
float im_min = -1.2;

float re_max = 1.0;
float im_max = 1.2;

double iterazioni = 255;


double r;

float a,b;
float x,y,x_new,y_new;

int test;

int k,j,i;

int keypress = 0;


int main() {

pngwriter png(SCREEN_WIDTH, SCREEN_HEIGHT,0,"mandelbrot.png");

float re_factor = (re_max-re_min);
float im_factor = (im_max-im_min);

for (i=0;i<SCREEN_HEIGHT;i++)
{
for (j=0;j<SCREEN_WIDTH;j++)
{
a = re_min+(j*re_factor/SCREEN_WIDTH);
b = im_min+(i*im_factor/SCREEN_HEIGHT);

x = 0;
y = 0;
test = 0;

for (k=0;k<iterazioni;k++)
{
x_new = (x*x)-(y*y)+a;
y_new = (2*x*y)+b;
if (((x_new*x_new)+(y_new*y_new))>4)
{
r = k%2;
png.plot(j,i, r, r, r);
break;
}
x = x_new;
y = y_new;
}
       
}

}
png.close();
return(0);

}

Geologi

  E so anche espatriare senza praticamente toccare strada asfaltata