#include #include #include #include #pragma pack(1) typedef struct { char type[2]; int file_size; int reserved; int offset; } bmpheader_t; #pragma pack(8) #pragma pack(1) typedef struct { int size; int width; int height; short planes; short bpp; int compression; int image_size; int xres; int yres; int clr_used; int clr_important; } dib_t; #pragma pack(8) #pragma pack(1) typedef struct { bmpheader_t header; dib_t dib; } bitmap_t; #pragma pack(8) char *tga_24to32(int width, int height, char *pBits, bool bgr) { int lImageSize = width * height * 4; char *pNewBits = new char[lImageSize * sizeof(char)]; for (int i = 0, j = 0; i < lImageSize; i += 4) { if (bgr) { pNewBits[i + 2] = pBits[j++]; pNewBits[i + 1] = pBits[j++]; pNewBits[i + 0] = pBits[j++]; } else { pNewBits[i + 0] = pBits[j++]; pNewBits[i + 1] = pBits[j++]; pNewBits[i + 2] = pBits[j++]; } pNewBits[i + 3] = 0; } return pNewBits; } void read_bitmap(char *filename, int &width, int &height, int **data) { FILE *file; bitmap_t bitmap; memset(&bitmap, 0, sizeof(bitmap_t)); file = fopen(filename, "rb"); if (file == NULL) { perror("Unable to write file"); *data = NULL; return; } fread(&bitmap, 1, sizeof(bitmap_t), file); width = bitmap.dib.width; height = bitmap.dib.height; *data = new int[width * height]; fread((void *)*data, 1, width * height * 4, file); fclose(file); if (bitmap.dib.bpp == 24) { int *old = *data; *data = (int *)tga_24to32(width, height, (char *)*data, false); delete[] old; } } void write_bitmap(char *filename, int width, int height, int *data) { FILE *file; bitmap_t bitmap; memset(&bitmap, 0, sizeof(bitmap_t)); memcpy(bitmap.header.type, "BM", 2); bitmap.header.offset = sizeof(bmpheader_t); bitmap.dib.size = sizeof(dib_t); bitmap.dib.width = width; bitmap.dib.height = height; bitmap.dib.planes = 1; bitmap.dib.bpp = 32; bitmap.dib.compression = 0; bitmap.dib.image_size = width * height * sizeof(int); bitmap.header.file_size = sizeof(bmpheader_t) + sizeof(dib_t) + bitmap.dib.image_size; file = fopen(filename, "wb"); if (file == NULL) { perror("Unable to write file"); return; } fwrite(&bitmap, 1, sizeof(bitmap_t), file); fwrite((void *)data, 1, width * height * 4, file); fclose(file); } inline int imin(int x, int y) { return y ^ ((x ^ y) & -(x < y)); } inline int imax(int x, int y) { return y ^ ((x ^ y) & -(x > y)); } inline void iclamp(int &a, int mi, int ma) { a = imin(imax(a, mi), ma); } void draw_line(int *pixels, int width, int height, int x1, int y1, int x2, int y2, int color) { int i; int x, y; float slope; int deltax; int deltay; iclamp(x1, 0, width - 1); iclamp(y1, 0, height - 1); iclamp(x2, 0, width - 1); iclamp(y2, 0, height - 1); deltax = abs(x2 - x1); deltay = abs(y2 - y1); if (deltax == 0 && deltay == 0) return; //We want x to always move right if (x2 - x1 < 0) { draw_line(pixels, width, height, x2, y2, x1, y1, color); return; } if (x2 - x1 != 0) { slope = (float)(y2 - y1) / (x2 - x1); } else { slope = 1000.0f; } if (slope > 1.0f) { //slope is greater than one, flip axis, redo everything if (y2 - y1 < 0) { draw_line(pixels, width, height, x2, y2, x1, y1, color); return; } slope = 1.0f / slope; for (i = 0; i <= deltay; i++) { y = y1 + i; x = x1 + slope * i; pixels[x + y * width] = color; } } else if (slope < -1.0f) { if (y2 - y1 < 0) { int temp; temp = y2; y2 = y1; y1 = temp; temp = x2; x2 = x1; x1 = temp; } slope = 1.0f / slope; for (i = 0; i <= deltay; i++) { y = y1 + i; x = x1 + slope * i; pixels[x + y * width] = color; } } else { for (i = 0; i <= deltax; i++) { x = x1 + i; y = y1 + slope * i; pixels[x + y * width] = color; } } } #define WIDTH 640 #define HEIGHT 480 #define CENTERX (WIDTH / 2) #define CENTERY (HEIGHT / 2) #define RADIUS 200 void dda_line(int *pixels, int width, int height, int x1, int y1, int x2, int y2, int color) { float x = x1; float y = y1; int dx, dy; float fdx, fdy; float step; int i; dx = (x2 - x1); dy = (y2 - y1); if (abs(dx) >= abs(dy)) step = abs(dx); else step = abs(dy); fdx = dx / step; fdy = dy / step; for (i = 1; i <= step; i++) { pixels[(unsigned int)x + (unsigned int)y * width] = color; x += fdx; y += fdy; } } int main(void) { static int data[WIDTH * HEIGHT] = { 0 }; for (int x = 0; x < 360; x++) { dda_line(data, WIDTH, HEIGHT, CENTERX, CENTERY, RADIUS * cos(x * 3.141592 / 180) + CENTERX, RADIUS * sin(x * 3.141592 / 180) + CENTERY, 0x0000FF00); } write_bitmap("out.bmp", WIDTH, HEIGHT, data); return 0; }