Tuesday, September 8, 2009

Midpoint Circle Algorithm



/*************************************************
* Midpoint Circle Algorithm *
*************************************************
* Usage :- Optimized and general method for rasterizing circles
* Author :- Rooparam Choudhary
* Date :- August 29, 2009 [3:40 PM IST]
* Place :- Shri Mata Vaishno Devi University
* EntryNo :- 2006ECS20
*/

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

inline void setpixel(int, int);
void unionJack(void);
void randomUnionJack(int);
void circleMidpoint(int, int, int);
inline void draw(int, int, int, int);
void wait(void);

int MYCOLOR = WHITE;
clock_t DELAY = 0;

void wait(void) {
clock_t init = clock();
while( (clock() - init) < DELAY)
;
}

/* Circle drawing algorithm */
void circleMidpoint(int xc, int yc, int r) {
int p = 1 - r;
int x = 0, y = r;
do{
draw(xc, yc, x, y);
++x;
if (p < 0)
p += 1 + (x<<1);
else{
--y;
p += 1 - ((y-x) << 1) ;
}
wait();
}while(y >= x);
}

/* Using the symmetry of Circle to draw points in other octants */
inline void draw(int xc, int yc, int x, int y) {
setpixel(xc+x, yc+y); // Ist Octant
setpixel(xc+y, yc+x); // IInd Octant
setpixel(xc-y, yc+x); // IIIrd Octant
setpixel(xc-x, yc+y); // IVth Octant
setpixel(xc-x, yc-y); // Vth Octant
setpixel(xc-y, yc-x); // VIth Octant
setpixel(xc+y, yc-x); // VIIth Octant
setpixel(xc+x, yc-y); // VIIIth Octant
}

inline void setpixel(int x, int y){
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 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); }
}
}

int main(void) {
int gd = DETECT, gm;
char *author = "Coder:- Rooparam Choudhary";
char *algo = "Midpoint Circle 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);

setcolor(YELLOW);
// X-axis
line(0, 239, 640, 239);
line(0, 240, 640, 240);
line(0, 241, 640, 241);
// Y-axis
line(319, 0, 319, 480);
line(320, 0, 320, 480);
line(321, 0, 321, 480);
// Y + X = 0
line(80, 0, 560, 480);
// Y - X = 0
line(80, 480, 560, 0);

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 xc, yc, r;

MYCOLOR = WHITE;
std::cout << "\nDelay Interval [0 - 100]\t Recommended: 20\n\n";
std::cout << "Enter the coordinates of circle center and it's radius and delay\n[xc yc r delay] (\'-400\' to exit) : ";

std::cin >> xc;
while(xc != -400) {
std::cin >> yc >> r >> DELAY;
sprintf(point, "(%3d, %3d) %3d", xc, yc, r);
setpixel(xc, yc);
line(320+xc, 240-yc, 320+xc+r, 240-yc);
outtextxy(320+xc-textwidth(point)/2, 240-yc+2, point);
circleMidpoint(xc, yc, r);

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

std::cout << "[xc yc r delay] (\'-400\' to exit) : ";
std::cin >> xc;
}

closegraph();
return 0;
}

No comments: