Skip to content

Instantly share code, notes, and snippets.

@martinlk
Created February 16, 2012 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martinlk/1846216 to your computer and use it in GitHub Desktop.
Save martinlk/1846216 to your computer and use it in GitHub Desktop.
Sierpinski BMP generator
//
// Martin Klingensmith
// Sierpinski BMP generator.
// 2012
// Uses crappy Bresenham line drawing.
//
#include <stdio.h>
#include <math.h>
#define WIDTH 800
#define HEIGHT 800
typedef __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int16 uint16_t;
void line(int x1, int y1, int x2, int y2); // Draw line
void plot(int x, int y, uint32_t color); // Plot pixel
void triangles(int Ax, int Ay, int Bx, int By, int Cx, int Cy);
//
// BMP Magic value
//
struct {
unsigned char magic[2];
} bmpmagic;
//
// BMP header
//
struct {
uint32_t filesz;
uint16_t creator1;
uint16_t creator2;
uint32_t bmp_offset;
} bmpheader;
//
// DIB header
//
struct {
uint32_t header_sz;
int32_t width;
int32_t height;
uint16_t nplanes;
uint16_t bitspp;
uint32_t compress_type;
uint32_t bmp_bytesz;
int32_t hres;
int32_t vres;
uint32_t ncolors;
uint32_t nimpcolors;
} dib;
//
// Pixel
//
typedef struct px {
char b;
char g;
char r;
} px;
px pixels[WIDTH+1][HEIGHT];
uint32_t color;
int main()
{
int x=0;
uint16_t rowsize;
//
// Start BMP
//
FILE *outfile = fopen("file.bmp","w");
if (outfile == NULL){
fprintf(stderr,"Can't open file\n");
}
bmpmagic.magic[0] = 0x42;
bmpmagic.magic[1] = 0x4D;
bmpheader.creator1 = 0;
bmpheader.creator2 = 0;
bmpheader.bmp_offset = sizeof(bmpmagic) + sizeof(bmpheader) + sizeof(dib);
dib.header_sz = sizeof(dib);
dib.width = WIDTH;
dib.height = HEIGHT;
dib.nplanes = 1;
dib.bitspp = 24;
dib.compress_type = 0;
rowsize = dib.bitspp * WIDTH * 4 / 32; // row size, bytes
rowsize += rowsize%4; // make multiple of 4 bytes
dib.bmp_bytesz = rowsize * HEIGHT;
dib.hres = 2835;
dib.vres = 2835;
dib.ncolors = 0;
dib.nimpcolors = 0;
bmpheader.filesz = dib.bmp_bytesz + 54;
//
// Write BMP header
//
fwrite(&bmpmagic,1,sizeof(bmpmagic),outfile);
fwrite(&bmpheader,1,sizeof(bmpheader),outfile);
fwrite(&dib,1,sizeof(dib),outfile);
//
// Initialize pixel buffer
//
memset(&pixels,0x0,sizeof(pixels));
//
// Draw triangles
//
triangles(0,0,WIDTH/2,HEIGHT/1.414,WIDTH,0);
//
// Write pixels to BMP
//
for(x=0;x<HEIGHT;x++)
{
fwrite(&(pixels[x]),1,3*WIDTH+3*WIDTH%4,outfile);
}
fclose(outfile);
return 0;
}
//
// Draw Sierpinski triangles
//
void triangles(int Ax, int Ay, int Bx, int By, int Cx, int Cy)
{
int Ex, Ey;
int Dx, Dy;
int Fx, Fy;
if(abs(Ax-Cx) < 8) return;
color = 0x0000FF;
line(Cx,Cy,Ax,Ay); // blue
color = 0xFF0000;
line(Ax,Ay,Bx,By); // red
color = 0x00FF00;
line(Bx,By,Cx,Cy); // green
// A-D-E
Ex = Ax+(Cx-Ax)/2;
Ey = Ay;
Dx = Ax + (Ex-Ax)/2;
Dy = Ay + (By-Ay)/2;
triangles(Ax,Ay,Dx,Dy,Ex,Ey);
// E-F-C
Fx = Bx + (Cx-Bx)/2;
Fy = Cy + (By-Cy)/2;
triangles(Ex,Ey,Fx,Fy,Cx,Cy);
// D-B-F
triangles(Dx,Dy,Bx,By,Fx,Fy);
return;
}
//
// Bresenham line drawing function
//
void line(int x1, int y1, int x2, int y2)
{
int dx = abs(x2 - x1);
int dy = abs(y2 - y1);
int sx = -1;
int sy = -1;
float err = dx - dy;
float e2;
int y = y1;
int x;
printf("\nline #%6X (%d,%d) to (%d,%d)",color,x1,y1,x2,y2);
if(x1<x2) sx = 1;
if(y1<y2) sy = 1;
do {
plot(x1,y1,color);
e2 = 2*err;
if(e2 > -dy){
err = err - dy;
x1 += sx;
}
if(e2 < dx){
err = err + dx;
y1 += sy;
}
} while((x1!=x2)||(y1!=y2));
return;
}
//
// Pixel poke
//
void plot(int x, int y, uint32_t col)
{
pixels[y][x].r = (col >> 16) & 0xFF;
pixels[y][x].g = (col >> 8) & 0xFF;
pixels[y][x].b = col & 0xFF;
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment