Tuesday, September 8, 2009

Midpoint Ellipse Algorithm



/*************************************************
* Midpoint Ellipse Algorithm *
*************************************************
* Usage :- Optimized and general method for rasterizing ellipses
* Author :- Rooparam Choudhary
* Date :- September 1, 2009 [3:15 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 ellipseMidpoint(int, 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)
;
}

/* Ellipse drawing algorithm */
void ellipseMidpoint(int xc, int yc, int rx, int ry) {
long long int rx_2 = rx*rx, ry_2 = ry*ry;
long long int p = ry_2 - rx_2*ry + (ry_2>>2);
int x = 0, y = ry;
long long int two_ry_2_x = 0, two_rx_2_y = (rx_2<<1)*y;
draw(xc, yc, x, y);
while(two_rx_2_y >= two_ry_2_x){
++x;
two_ry_2_x += (ry_2<<1);

p += two_ry_2_x + ry_2;

if(p >= 0){
--y;
two_rx_2_y -= (rx_2<<1);

p -= two_rx_2_y ;
}
wait();
draw(xc, yc, x, y);
}

p = (long long int)(ry_2*(x+1/2.0)*(x+1/2.0) + rx_2*(y-1)*(y-1) - rx_2*ry_2);
while (y>=0) {
p += rx_2;
--y;
two_rx_2_y -= (rx_2<<1);
p -= two_rx_2_y;

if(p <= 0) {
++x;
two_ry_2_x += (ry_2<<1);
p += two_ry_2_x;
}
wait();
draw(xc, yc, x, y);
}
}

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

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 Ellipse 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, rx, ry;

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

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

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 rx ry delay] (\'-400\' to exit) : ";
std::cin >> xc;
}

closegraph();
return 0;
}

3 comments:

jeetan said...

kya yaar, kuch bhi

Unknown said...

http://www.muengg.org/forum/-sem-4-practicals-midpoint-ellipse-program-in-c++-for-cg-t134.html


This one is way simpler than the one written above!

rooparam said...

@webmaster : but ur link ask for a file to be downloaded for code