Created
February 16, 2012 16:26
-
-
Save martinlk/1846216 to your computer and use it in GitHub Desktop.
Sierpinski BMP generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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