Tuesday, September 8, 2009

Bresenham's Line Drawing Algorithm



/*************************************************
* Bresenham's Line Drawing Algorithm *
*************************************************
* Usage :- Optimized and general method for rasterizing lines and triangles
* Author :- Rooparam Choudhary
* Date :- August 29, 2009
* Place :- Shri Mata Vaishno Devi University
* EntryNo :- 2006ECS20
*/

#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <iostream>
#include <math.h>

inline void setpixel(int, int);
void BHM(int, int, int, int);
void drawLine(int, int, int, int);
void unionJack(void);
void hexagon(int, int);
void randomUnionJack(int);

int MYCOLOR = WHITE;
int INVERSE = 0; // 0 : false 1 : true
int SIGN = 0; // 0 : y = x 1 : y = -x

inline void setpixel(int x, int y){
if(INVERSE){
if(SIGN)
putpixel(320-y, 240+x, MYCOLOR);
else
putpixel(320+y, 240-x, MYCOLOR);
} else
putpixel(320+x, 240-y, MYCOLOR);
}

void randomUnionJack(int count){
void DJ(int, int, int);
int xr, yr, clr=0;
srand(time(NULL));

while(count-- > 0){
xr = -320 + rand()%641;
yr = -240 + rand()%481;
clr = 0;
if(yr > -xr){
if(xr < 0) clr = 3;
else if(yr < 0) clr = 2;
else if(yr > xr) clr = 4;
else if(yr < xr) clr = 1;
}else if(yr < -xr) {
if(xr > 0) clr = 3;
else if(yr > 0) clr = 2;
else if(yr < xr) clr = 4;
else if(yr > xr) clr = 1;
}
DJ(xr, yr, clr);
}
}

void DJ(int x, int y, int clr){
int shade = 0;
switch(clr){
case 1: shade = RED; break;
case 2: shade = BLUE; break;
case 3: shade = CYAN; break;
case 4: shade = MAGENTA; break;
default: return; break;
}
putpixel(320+x, 240-y, shade);
}

void BHM(int x0, int y0, int x1, int y1){
int twoDY = 2*(y1-y0), twoDX = 2*(x1-x0), DX = x1-x0;
int incY = ((twoDY < 0) ? -1 : 1);
twoDY = abs(twoDY);
int p = twoDY - DX; int x = x0, y = y0;

setpixel(x, y);

while(x < x1) {
++x;
if(!(p<0)) {
y += incY;
p -= twoDX;
}
p += twoDY;
setpixel(x, y);
}
}

void drawLine(int x0, int y0, int x1, int y1) {
INVERSE = 0;
SIGN = 0;
float m = 0;
int t;
int infinity = (x1 == x0);

if(!infinity)
m = (y1-y0) / (float)(x1-x0);
if(m < 0)
SIGN = 1;

if(infinity || fabs(m) > 1) {
INVERSE = 1;

if(SIGN)
{ t = -x0; x0 = -y0; y0 = t;
t = -x1; x1 = -y1; y1 = t; }
else
{ t = x0; x0 = y0; y0 = t;
t = x1; x1 = y1; y1 = t; }
}

if(x1<x0)
BHM(x1, y1, x0, y0);
else
BHM(x0, y0, x1, y1);
}

void unionJack(){
for(int y = 240; y>0; --y) {
int x = -321;

MYCOLOR = BLUE;
while(++x < -y)
{ putpixel(320+x, 240-y, MYCOLOR); }
MYCOLOR = CYAN;
while(++x < 0)
{ putpixel(320+x, 240-y, MYCOLOR); }
MYCOLOR = MAGENTA;
while(++x < y)
{ putpixel(320+x, 240-y, MYCOLOR); }
MYCOLOR = RED;
while(++x < 321)
{ putpixel(320+x, 240-y, MYCOLOR); }
}
for(int y = -1; y>-241; --y) {
int x = -321;

MYCOLOR = RED;
while(++x < y)
{ putpixel(320+x, 240-y, MYCOLOR); }
MYCOLOR = MAGENTA;
while(++x < 0)
{ putpixel(320+x, 240-y, MYCOLOR); }
MYCOLOR = CYAN;
while(++x < -y)
{ putpixel(320+x, 240-y, MYCOLOR); }
MYCOLOR = BLUE;
while(++x < 321)
{ putpixel(320+x, 240-y, MYCOLOR); }
}
}
void hexagon(int xc, int yc) {
drawLine(xc+60, yc+104, xc+120, yc);
drawLine(xc+60, yc+104, xc+60, yc-104);
drawLine(xc+60, yc+104, xc-60, yc-104);
drawLine(xc+60, yc+104, xc-120, yc);
drawLine(xc+60, yc+104, xc-60, yc+104);
drawLine(xc+120, yc, xc+60, yc-104);
drawLine(xc+120, yc, xc-60, yc-104);
drawLine(xc+120, yc, xc-120, yc);
drawLine(xc+120, yc, xc-60, yc+104);
drawLine(xc+60, yc-104, xc-60, yc-104);
drawLine(xc+60, yc-104, xc-120, yc);
drawLine(xc+60, yc-104, xc-60, yc+104);
drawLine(xc-60, yc-104, xc-120, yc);
drawLine(xc-60, yc-104, xc-60, yc+104);
drawLine(xc-120, yc, xc-60, yc+104);
}

int main(void) {
int gd = DETECT, gm;
char *author = "Coder:- Rooparam Choudhary";
char *algo = "Bresenham's Line Drawing Algorithm";
char point[30];
std::cout << algo << std::endl;
std::cout << author << std::endl;
initgraph(&gd, &gm, "C:\\");

setcolor(WHITE);
setbkcolor(GREEN);
outtextxy(320 - textwidth(algo)/2, 5, algo);
outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
setcolor(GREEN);
setbkcolor(BLACK);

MYCOLOR = GREEN;
// X-axis
drawLine(-320, -1, 320, -1);
drawLine(-320, 0, 320, 0);
drawLine(-320, 1, 320, 1);
// Y-axis
drawLine(-1, 240, -1, -240);
drawLine( 0, 240, 0, -240);
drawLine( 1, 240, 1, -240);
// Y - X = 0
drawLine(-240, -240, 240, 240);
// Y + X = 0
drawLine(-240, 240, 240, -240);

MYCOLOR = BROWN;
hexagon(-160, 120);
hexagon(160, 120);
hexagon(160, -120);
hexagon(-160, -120);

std::cout << "Enter samples for union jack\n(SHOULD BE GEATER THAN 100K): ";
int samp;
std::cin >> samp;
//unionJack();
randomUnionJack(samp);

setcolor(WHITE);
setbkcolor(GREEN);
outtextxy(320 - textwidth(algo)/2, 5, algo);
outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
setcolor(GREEN);
setbkcolor(BLACK);

int x0, y0, x1, y1;
MYCOLOR = WHITE;
std::cout << "Enter \'-400\' to exit\n";
std::cout << "Enter the coordinates of end points: [x0 y0 x1 y1]\n";

std::cin >> x0;
while(x0 != -400) {
std::cin >> y0 >> x1 >> y1;
sprintf(point, "(%4d, %4d)", x0, y0);
outtextxy(320+x0-textwidth(point)/2, 240-y0+2, point);
sprintf(point, "(%4d, %4d)", x1, y1);
outtextxy(320+x1-textwidth(point)/2, 240-y1+2, point);
drawLine(x0, y0, x1, y1);

setcolor(WHITE);
setbkcolor(GREEN);
outtextxy(320 - textwidth(algo)/2, 5, algo);
outtextxy(getmaxx()-4 -textwidth(author), getmaxy()-20, author);
setcolor(GREEN);
setbkcolor(BLACK);

std::cin >> x0;
}

closegraph();
return 0;
}

No comments: