I was using another coloring scheme that produced very blue pictures .. just this morning I have implemented smooth coloring properly and its made a huge difference ..
I want to use my first program to find nice shots and then crunch it with my second .. lets me use the computer without having to worry about clicking on the mandelbrot set picture and wrecking hours of work ..
Im going to try and merge them together but just happy that today it works ..
heres my code the first uses c and sdl the second straight c .. Im using debian squeeze amd64 and gcc 4.4.5
regards the padding the only problem I have is that the image has to be a multiple of 4 pixels wide .. so my image which should be 809 x 500 is 812 x 500 which leaves a 3 pixel wide black side edge .. something Im prepared to put up with ..
pressing keyboard 2 doubles image size
pressing 3 increases both max iterations and escape value
pressing 4 doubles both max iterations and escape value
pressing b takes you back .. first time you have to press twice .. because it draws the same screen again before going back
press s to save
press esc to quit.
program two pump the values in and wait .. default to the whole set and a very low number of iterations ..
next step is using bignums ..
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<SDL/SDL.h>
#define smooth log( 0.5 * log( window->ESCAPE ))
SDL_Surface *screen;
SDL_Event event;
struct window{
int xscreen,yscreen,Nxscreen,Nyscreen;
int a,b,c,d;
unsigned long long int MAX,ESCAPE;
long double ximage,yimage,xoff,yoff;
};
struct data{
int Nxscreen[50],Nyscreen[50];
long double ximage[50],yimage[50],xoff[50],yoff[50];
};
struct pxcolor{
int r;
int g;
int b;
}arraycolor[512],*prgb;
void write_data(struct data* data);
struct window *image_size( struct window* window );
struct window *window_size( struct window* window );
struct window *mouse( int z, struct window* window );
void putpixel( int x, int y, Uint32 colors );
Uint32 getcolor( int count,struct window* window, struct pxcolor* prgb );
int multiply(long double real, long double imaginary,struct window* window );
void numbers( struct window* window, struct pxcolor* prgb );
void repeat( struct window* window, struct pxcolor* prgb );
void control( struct window* window, struct data* data, struct pxcolor* prgb );
void start( );
void numbers( struct window* window, struct pxcolor* prgb );
void unlock();
void lock();
void sdl( struct window* window );
void write_data(struct data* data){
FILE *fp;
int c;
fp = fopen("image_info","w");
for(c = 0;c < 50; c++){
fprintf(fp,"c = %i\n",c);
fprintf(fp,"Nxscreen = %i\n",data->Nxscreen[c]);
fprintf(fp,"Nyscreen = %i\n",data->Nyscreen[c]);
fprintf(fp,"ximage = %.40Lf\n",data->ximage[c]);
fprintf(fp,"yimage = %.40Lf\n",data->yimage[c]);
fprintf(fp,"xoff = %.40Lf\n",data->xoff[c]);
fprintf(fp,"yoff = %.40Lf\n",data->yoff[c]);
}
fclose(fp);
}
struct window *image_size( struct window* window ){
long double s,t,u,v,z;
z = window->ximage / window->Nxscreen;
s = z * window->c - window->xoff;
u = z * window->a - window->xoff;
z = window->yimage / window->Nyscreen;
t = window->yoff - ( z * window->d );
v = window->yoff - ( z * window->b );
window->ximage = u - s;
window->yimage = t - v;
window->xoff = -s;
window->yoff = t;
return window;
}
struct window *window_size( struct window* window ){
int t;
window->Nxscreen = window->a - window->c;
window->Nyscreen = window->b - window->d;
if( window->Nxscreen > window->Nyscreen ){
t = window->xscreen / window->Nxscreen;
}
else{
t = window->yscreen / window->Nyscreen;
}
window->Nxscreen = window->Nxscreen * t;
window->Nyscreen = window->Nyscreen * t;
return window;
}
struct window *mouse( int z, struct window* window ){
if( z == 1 ){
window->c = event.button.x;
window->d = event.button.y;
}
if( z != 1 ){
window->a = event.button.x;
window->b = event.button.y;
}
return window;
}
void putpixel( int x, int y, Uint32 colors ){
Uint32 *bufp;
bufp = ( Uint32 *)screen->pixels + y*screen->pitch / 4 + x;
*bufp = colors;
}
Uint32 getcolor( int count, struct window* window, struct pxcolor* prgb ){
int red = prgb[( count % 512 )].r;
int green = prgb[( count % 512 )].g;
int blue = prgb[( count % 512 )].b;
Uint32 colors;
if(count == window->MAX){
return( colors = SDL_MapRGB(screen->format,0,0,0));
}
else{
return colors = SDL_MapRGB(screen->format,
( blue ),( green ),( red ));
}
}
int multiply(long double real, long double imaginary, struct window* window ){
int count = 1;
long double x,y,z = 0,xx,yy,tempr = real,tempi = imaginary;
while( count < window->MAX &&
abs( z ) < window->ESCAPE ){
x = tempr * tempr;
y = tempi * tempi;
z = tempr * tempi;
xx = x - y;
yy = 2 * z;
z = x + y;
tempr = real + xx;
tempi = imaginary + yy;
count++;
}
if(count >= window->MAX ){
return count;
}
else{
return ( count - ( log( 0.5 * log( z )) - smooth ) / log( 2 ));
}
}
void numbers( struct window* window, struct pxcolor* prgb ){
int x,y,count;
Uint32 colors;
long double real,imaginary, convx,convy;
convx = window->ximage / window->Nxscreen;
convy = window->yimage / window->Nyscreen;
for( x = 1; x < window->Nxscreen; x++ ){
for( y = 1; y < window->Nyscreen; y++ ){
real = convx * x - window->xoff;
imaginary = window->yoff - ( convy * y );
count = multiply( real, imaginary, window );
colors = getcolor( count, window, prgb);
putpixel( x, y, colors );
}
}SDL_UpdateRect( screen,0,0,window->Nxscreen,window->Nyscreen );
printf("draw finish\n");
}
void repeat( struct window* window, struct pxcolor* prgb){
sdl( window );
lock();
numbers( window,prgb );
unlock();
}
void control(struct window* window, struct data* data, struct pxcolor* prgb ){
int c = 1;
int z = 1;
while( SDL_WaitEvent( &event )){
switch( event.type ){
case SDL_MOUSEBUTTONDOWN:{
if (event.button.button == SDL_BUTTON_LEFT){
mouse( z, window );
if( z != 1 ){
image_size( window );
window_size( window );
data->Nxscreen[c] = window->Nxscreen;
data->Nyscreen[c] = window->Nyscreen;
data->ximage[c] = window->ximage;
data->yimage[c] = window->yimage;
data->xoff[c] = window->xoff;
data->yoff[c] = window->yoff;
c++;
repeat( window, prgb );
}
z = -z;
}
break;
}
case SDL_KEYDOWN:{
/***DOUBLE WINDOW SIZE***/
if( event.key.keysym.sym == SDLK_2 ){
window->Nxscreen = window->Nxscreen * 2;
window->Nyscreen = window->Nyscreen * 2;
repeat( window, prgb );
}
if( event.key.keysym.sym == SDLK_3 ){
window->MAX = 4096;
window->ESCAPE = 100;
repeat( window, prgb );
}
if( event.key.keysym.sym == SDLK_4 ){
window->MAX = window->MAX * 2;
window->ESCAPE = window->ESCAPE * 2;
repeat( window, prgb );
}
if( event.key.keysym.sym == SDLK_b ){
c = c - 1;
window->Nxscreen = data->Nxscreen[c];
window->Nyscreen = data->Nyscreen[c];
window->ximage = data->ximage[c];
window->yimage = data->yimage[c];
window->xoff = data->xoff[c];
window->yoff = data->yoff[c];
repeat( window, prgb );
}
if( event.key.keysym.sym == SDLK_s ){
SDL_SaveBMP( screen, "shot.bmp" );
}
if( event.key.keysym.sym == SDLK_ESCAPE ){
write_data(data);
return( SDL_Quit());
}
break;
}
}}
}
void unlock(){
if( SDL_MUSTLOCK( screen )){
SDL_UnlockSurface( screen );
}
}
void lock(){
if( SDL_MUSTLOCK( screen )){
if( SDL_LockSurface( screen ) < 0 ){
return;
}
}
}
void sdl( struct window* window ){
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE );
SDL_WM_SetCaption("smooth.c",NULL);
screen = SDL_SetVideoMode
( window->Nxscreen,window->Nyscreen,
32,SDL_SWSURFACE );
}
void start( ){
int c;
struct window wdw;
struct window *window;
window = &wdw;
struct data dta;
struct data *data;
data = &dta;
prgb = arraycolor;
window->MAX = 128;
window->ESCAPE = 4;
window->xscreen = 809;
window->yscreen = 500;
window->Nxscreen = window->xscreen;
window->Nyscreen = window->yscreen;
window->ximage = 3.2;
window->yimage = 2.0;
window->xoff = 2.2;
window->yoff = 1.0;
for(c = 0; c < 50; c++){
data->Nxscreen[c] = 0;
data->Nyscreen[c] = 0;
data->ximage[c] = 0;
data->yimage[c] = 0;
data->xoff[c] = 0;
data->yoff[c] = 0;
}
//make sure initial image is avaliable so no further attempt to go back is made.
data->Nxscreen[0] = 809;
data->Nyscreen[0] = 500;
data->ximage[0] = 3.2;
data->yimage[0] = 2.0;
data->xoff[0] = 2.2;
data->yoff[0] = 1.0;
for( c = 0; c < 512; c++ ){
prgb[c].r = 0;
prgb[c].g = 0;
prgb[c].b = 0;
}
for( c = 0; c < 512; c++ ){
prgb[c].r = c % 256;
prgb[c].g = ( c + 32 ) % 256;
prgb[c].b = ( c + 64 ) % 256;
}
repeat( window, prgb );
control( window, data, prgb );
}
int main( int argc, char * argv[] ){
start();
return(0);
}
and the 2nd
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<inttypes.h>
#define smooth log( 0.5 * log( window->ESCAPE ))
//prototyping the structures ..
struct window{
int Nxscreen,Nyscreen;
unsigned long long int MAX,ESCAPE;
long double ximage,yimage,xoff,yoff;
}wdw,*window;
struct pxcolor{
int r[512];
int g[512];
int b[512];
}rgb,*prgb;
struct bmp{
unsigned char magic[2]; // "BM"
}bfp,*bf
;
struct header{
uint32_t filesize; // Size of file in bytes
uint16_t creator1; //Set to 0
uint16_t creator2; // Set to 0
uint32_t offset; // Byte offset to actual bitmap data (= 54)
uint32_t headersize; // Size of BITMAPINFOHEADER, in bytes (= 40)
int32_t width; // Width of image, in pixels
int32_t height; // Height of images, in pixels
uint16_t nplanes; // Number of planes in target device (set to 1)
uint16_t bitsperpixel; // Bits per pixel
uint32_t compressiontype; // Type of compression (0 if no compression)
uint32_t bitmapbytesize; // Image size, in bytes (0 if no compression)<----remember 0
int32_t hres; // Resolution in pixels/ meter of display device
int32_t vres; // Resolution in pixels/ meter of display device
uint32_t ncolors; // Number of colors in the color table (if 0, use maximum allowed by biBitCount)
uint32_t nimpcolors; // Number of important colors. If 0, all colors are important
}bmp,*hp;
struct rgb{
unsigned char r;
unsigned char g;
unsigned char b;
};
//prototype the functions ..
struct rgb *color( long long int count,struct window* window,
struct rgb* thc, int x,
struct pxcolor* prgb );
int multiply(long double real, long double imaginary,struct window* window );
void control( struct window* window, int bpl, struct header* hp,
struct bmp* bf, struct pxcolor* prgb );
void start();
struct rgb *color( long long int count, struct window* window,
struct rgb* thc,int x,
struct pxcolor* prgb ){
int red = prgb->r[count];
int green = prgb->g[count];
int blue = prgb->b[count];
if(count == window->MAX){
thc[x].b = 0;
thc[x].g = 0;
thc[x].r = 0;
return( thc );
}
else{
thc[x].b = blue;
thc[x].g = green;
thc[x].r = red;
return(thc);
}
}
// multiply is an iterative process which returns a count which is
// converted into a color.
int multiply(long double real, long double imaginary, struct window* window ){
unsigned long long int count = 1;
long double x,y,z = 0,xx,yy,tempr = real,tempi = imaginary;
while( count < window->MAX &&
abs( z ) < window->ESCAPE ){
x = tempr * tempr;
y = tempi * tempi;
z = tempr * tempi;
xx = x - y;
yy = 2 * z;
z = x + y;
tempr = real + xx;
tempi = imaginary + yy;
count++;
}
if(count >= window->MAX ){
return count;
}
return ( count - ( log( 0.5 * log( z )) - smooth ) / log( 2 ));
}
void control( struct window* window, int bpl, struct header* hp,
struct bmp* bf, struct pxcolor* prgb ){
//create the array to hold each line colors ..
int x,y,count;
long double real,imaginary, convx,convy;
struct rgb array[ bpl ];
struct rgb *thc;
thc = array;
FILE *fp;
//zero array ..
for(count = 0; count < window->Nxscreen -1; count++ ){
thc[x].b = 0;
thc[x].g = 0;
thc[x].r = 0;
// array[x].reserve = 50;
}
//write the headers for the bitmap ..
fp = fopen("image-01.bmp","wb");
fwrite(bf,sizeof(bfp),1,fp);
fwrite(&bmp,sizeof(bmp),1,fp);
//imaginary number for each pixel
convx = window->ximage / window->Nxscreen;
convy = window->yimage / window->Nyscreen;
for( y = window->Nyscreen; y < 0; y++ ){
for( x = 1; x < window->Nxscreen; x++ ){
real = convx * x - window->xoff;
imaginary = window->yoff - ( convy * y );
count = multiply( real, imaginary, window );
color( count, window, thc, x, prgb );
}
//should have a full array here .. write it out .. draw line by line
fwrite(&array,sizeof(array),1,fp);
}
fclose( fp );
}
void start( ){
//setting the conditions for the bitmap .. also screen size and image size.
int bpl;
int c;
window = &wdw;
hp = &bmp;
bf = &bfp;
struct pxcolor arraycolor;
prgb = &arraycolor;
window->MAX = 1028;
window->ESCAPE = 400;
window->Nxscreen = 809;
window->Nyscreen = -500;
window->ximage = 3.2;
window->yimage = 2.0;
window->xoff = 2.2;
window->yoff = 1.0;
//make sure the Nxscreen is divisible by 4 ..
bpl = window->Nxscreen;
while(bpl % 4 != 0){
bpl++;
}
bf->magic[0] = 'B';
bf->magic[1] = 'M';
hp->creator1 = 0;
hp->creator2 = 0;
hp->offset = 54;
hp->filesize = hp->offset + (window->Nyscreen * bpl);
hp->width = bpl;
hp->height = -window->Nyscreen;
hp->nplanes = 1;
hp->bitsperpixel = 24;
hp->compressiontype = 0;
hp->bitmapbytesize = bpl * hp->height;
hp->hres = 2835;
hp->vres = 2835;
hp->ncolors = 0;
hp->nimpcolors = 0;
hp->headersize = hp->bitsperpixel + hp->bitmapbytesize;
//initialise all pxcolor elements to zero
for( c = 0; c < 512; c++ ){
prgb->r[c] = 0;
prgb->g[c] = 0;
prgb->b[c] = 0;
}
for( c = 0; c < 512; c++ ){
prgb->r[c] = c % 256;
prgb->g[c] = ( c + 32 ) % 256;
prgb->b[c] = ( c + 64 ) % 256;
}
control( window,bpl,hp,bf,prgb );
}
int main( int argc, char * argv[] ){
start(); //GO!!
return(0);
}