Task: Fractal tree

C: #include <SDL/SDL.h>
#ifdef WITH_CAIRO
#include <cairo.h>
#else
#include <SDL/sge.h>
#endif
#include <cairo.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#ifdef WITH_CAIRO
#define PI 3.1415926535
#endif
 
#define SIZE           800   
#define SCALE          5     
#define BRANCHES       14    
#define ROTATION_SCALE 0.75  
#define INITIAL_LENGTH 50    
 
double rand_fl(){
  return (double)rand() / (double)RAND_MAX;
}
 
void draw_tree(SDL_Surface * surface, double offsetx, double offsety,
               double directionx, double directiony, double size,
               double rotation, int depth) {
#ifdef WITH_CAIRO
  cairo_surface_t *surf = cairo_image_surface_create_for_data( surface->pixels,
                                                               CAIRO_FORMAT_RGB24,
							       surface->w, surface->h,
							       surface->pitch );
  cairo_t *ct = cairo_create(surf);

  cairo_set_line_width(ct, 1);
  cairo_set_source_rgba(ct, 0,0,0,1);
  cairo_move_to(ct, (int)offsetx, (int)offsety);
  cairo_line_to(ct, (int)(offsetx + directionx * size), (int)(offsety + directiony * size));
  cairo_stroke(ct);
#else
  sge_AALine(surface,
      (int)offsetx, (int)offsety,
      (int)(offsetx + directionx * size), (int)(offsety + directiony * size),
      SDL_MapRGB(surface->format, 0, 0, 0));
#endif
  if (depth > 0){
    
    draw_tree(surface,
        offsetx + directionx * size,
        offsety + directiony * size,
        directionx * cos(rotation) + directiony * sin(rotation),
        directionx * -sin(rotation) + directiony * cos(rotation),
        size * rand_fl() / SCALE + size * (SCALE - 1) / SCALE,
        rotation * ROTATION_SCALE,
        depth - 1);
 
    
    draw_tree(surface,
        offsetx + directionx * size,
        offsety + directiony * size,
        directionx * cos(-rotation) + directiony * sin(-rotation),
        directionx * -sin(-rotation) + directiony * cos(-rotation),
        size * rand_fl() / SCALE + size * (SCALE - 1) / SCALE,
        rotation * ROTATION_SCALE,
        depth - 1);
  }
}
 
void render(SDL_Surface * surface){
  SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 255, 255, 255));
  draw_tree(surface,
      surface->w / 2.0,
      surface->h - 10.0,
      0.0, -1.0,
      INITIAL_LENGTH,
      PI / 8,
      BRANCHES);
  SDL_UpdateRect(surface, 0, 0, 0, 0);
}
 
int main(){
  SDL_Surface * screen;
  SDL_Event evt;
 
  SDL_Init(SDL_INIT_VIDEO);
 
  srand((unsigned)time(NULL));
 
  screen = SDL_SetVideoMode(SIZE, SIZE, 32, SDL_HWSURFACE);
 
  render(screen);
  while(1){
    if (SDL_PollEvent(&evt)){
      if(evt.type == SDL_QUIT) break;
    }
    SDL_Delay(1);
  }
  SDL_Quit();
  return 0;
}


C++: #include <windows.h>
#include <string>
#include <math.h>


using namespace std;


const float PI = 3.1415926536f;


class myBitmap
{
public:
    myBitmap() : pen( NULL ) {}
    ~myBitmap()
    {
	DeleteObject( pen );
	DeleteDC( hdc );
	DeleteObject( bmp );
    }

    bool create( int w, int h )
    {
	BITMAPINFO	bi;
	void		*pBits;
	ZeroMemory( &bi, sizeof( bi ) );
	bi.bmiHeader.biSize	   = sizeof( bi.bmiHeader );
	bi.bmiHeader.biBitCount	   = sizeof( DWORD ) * 8;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biPlanes	   = 1;
	bi.bmiHeader.biWidth	   =  w;
	bi.bmiHeader.biHeight	   = -h;

	HDC dc = GetDC( GetConsoleWindow() );
	bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );
	if( !bmp ) return false;

	hdc = CreateCompatibleDC( dc );
	SelectObject( hdc, bmp );
	ReleaseDC( GetConsoleWindow(), dc ); 

	width = w; height = h;

	return true;
    }

    void setPenColor( DWORD clr )
    {
	if( pen ) DeleteObject( pen );
	pen = CreatePen( PS_SOLID, 1, clr );
	SelectObject( hdc, pen );
    }

    void saveBitmap( string path )
    {
	BITMAPFILEHEADER	fileheader;
	BITMAPINFO			infoheader;
	BITMAP				bitmap;
	DWORD*				dwpBits;
	DWORD				wb;
	HANDLE				file;

	GetObject( bmp, sizeof( bitmap ), &bitmap );

	dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];
	ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );
	ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );
	ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );

	infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
	infoheader.bmiHeader.biCompression = BI_RGB;
	infoheader.bmiHeader.biPlanes = 1;
	infoheader.bmiHeader.biSize = sizeof( infoheader.bmiHeader );
	infoheader.bmiHeader.biHeight = bitmap.bmHeight;
	infoheader.bmiHeader.biWidth = bitmap.bmWidth;
	infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD );

	fileheader.bfType    = 0x4D42;
	fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );
	fileheader.bfSize    = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;

	GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );

	file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );
	WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );
	WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );
	CloseHandle( file );

	delete [] dwpBits;
    }

    HDC getDC()     { return hdc; }
    int getWidth()  { return width; }
    int getHeight() { return height; }

private:
    HBITMAP bmp;
    HDC	    hdc;
    HPEN    pen;
    int     width, height;
};

class vector2
{
public:
    vector2() { x = y = 0; }
    vector2( int a, int b ) { x = a; y = b; }
    void set( int a, int b ) { x = a; y = b; }
    void rotate( float angle_r )
    {
	float _x = static_cast<float>( x ),
	      _y = static_cast<float>( y ),
	       s = sinf( angle_r ), 
	       c = cosf( angle_r ),
	       a = _x * c - _y * s, 
	       b = _x * s + _y * c;

	x = static_cast<int>( a ); 
	y = static_cast<int>( b );
    }

    int x, y;
};

class fractalTree
{
public:
    fractalTree()		      { _ang = DegToRadian( 24.0f ); }
    float DegToRadian( float degree ) { return degree * ( PI / 180.0f ); }

    void create( myBitmap* bmp )
    {
	_bmp = bmp;
	float line_len = 130.0f;

	vector2 sp( _bmp->getWidth() / 2, _bmp->getHeight() - 1 );
	MoveToEx( _bmp->getDC(), sp.x, sp.y, NULL );
	sp.y -= static_cast<int>( line_len );
	LineTo( _bmp->getDC(), sp.x, sp.y);

	drawRL( &sp, line_len, 0, true );
	drawRL( &sp, line_len, 0, false );
    }

private:
    void drawRL( vector2* sp, float line_len, float a, bool rg )
    {
	line_len *= .75f;
	if( line_len < 2.0f ) return;

	MoveToEx( _bmp->getDC(), sp->x, sp->y, NULL );
	vector2 r( 0, static_cast<int>( line_len ) );

        if( rg ) a -= _ang;
        else a += _ang; 

	r.rotate( a );
	r.x += sp->x; r.y = sp->y - r.y;

	LineTo( _bmp->getDC(), r.x, r.y );

	drawRL( &r, line_len, a, true );
	drawRL( &r, line_len, a, false );
    }

    myBitmap* _bmp;
    float     _ang;
};

int main( int argc, char* argv[] )
{
    ShowWindow( GetConsoleWindow(), SW_MAXIMIZE );

    myBitmap bmp;
    bmp.create( 640, 512 );
    bmp.setPenColor( RGB( 255, 255, 0 ) );

    fractalTree tree;
    tree.create( &bmp );
	
    BitBlt( GetDC( GetConsoleWindow() ), 0, 20, 648, 512, bmp.getDC(), 0, 0, SRCCOPY );

    bmp.saveBitmap( "f:
	
    system( "pause" );
	
    return 0;
}