Tuesday, September 8, 2009

Simple Circle Drawing Algorithm




/*************************************************
* Simple Circle Drawing Algorithm *
*************************************************
* Usage :- Simple and general method for rasterizing circles
* Author :- Rooparam Choudhary
* Date :- August 29, 2009 [12: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>

#define ROUND(x) ((x>0)?(int)(x+0.5):(int)(x-0.5))
#define PI 3.14159265

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

int MYCOLOR = WHITE;
clock_t DELAY = 0;

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 wait(void) {
clock_t init = clock();
while( (clock() - init) < DELAY)
;
}

/* Circle drawing algorithm */
void simpleCircle(float xc, float yc, float radius) {
float step = 1.0f / radius, theta = 0.0f;
float x = radius, y = 0.0f;
do{
draw(xc, yc, x, y);
theta += step;
x = radius*cos(theta);
y = radius*sin(theta);
wait();
}while(theta <= PI / 4.0f);
}

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

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

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 = "Simple Circle 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);

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);

float xc, yc, r;

MYCOLOR = WHITE;
std::cout << "Enter \'-400\' to exit\n";
std::cout << "Enter Delay: ";
std::cin >> DELAY;
std::cout << "Enter the coordinates of circle center and it's radius: [xc yc r]\n";

std::cin >> xc;
while((int)xc != (int)-400.0f ) {
std::cin >> yc >> r;
sprintf(point, "(%4.1f, %4.1f) %4.1f", xc, yc, r);
setpixel(ROUND(xc), ROUND(yc));
line(320+ROUND(xc), 240-ROUND(yc), 320+ROUND(xc+r), 240-ROUND(yc));
outtextxy(320+ROUND(xc)-textwidth(point)/2, 240-ROUND(yc)+2, point);
simpleCircle(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::cin >> xc;
}

closegraph();
return 0;
}

2 comments:

Anonymous said...

Turbo C? Oh c'mon, were in the 21st century.

rooparam said...

it's the implementation of turboC API on linux (ubuntu)

... because in india most colleges still teach graphics using turbo C API