PDA

View Full Version : Connect midpoint circle dots for circle outline



TalysShade
10-05-2012, 02:08 AM
Hello everyone,

I've just begun learning openGL and one of the first steps is to draw a circle using the bresenham/midpoint algorithm. The code actual works (so proud of myself! ... ) but, completely as expected there's only dots. What I would like is to actually complete the circle as in connect the dots. However, also as expected, turning glBegin(GL_POINTS) into glBegin(GL_LINE_STRIP) (or LINES for that matter) connects the wrong dots because of the algorithm. Google hasn't helped me yet and so completely against my normal customs I decided to post here.

How can I have the dots connect to get a full circle, instead of just a dotted one?

Below the code used for the algorithm. I simply call it with awCircle(0,0,10);


/************************************************** **************************
* Draw the actual circle points in each section.
************************************************** *************************/
void drawCirclePoints (int x, int y, int xc, int yc)
{
glBegin(GL_POINTS);
glVertex2i (xc+x,yc+y);
glVertex2i (xc-x,yc+y);
glVertex2i (xc+x,yc-y);
glVertex2i (xc-x,yc-y);
glVertex2i (xc+y,yc+x);
glVertex2i (xc-y,yc+x);
glVertex2i (xc+y,yc-x);
glVertex2i (xc-y,yc-x);
glEnd();
}


/************************************************** **************************
* Function to make sure all points of a whole circle get drawn
************************************************** *************************/
void awCircle (int xc, int yc, int rad)
{
int x,y,d;

x = 0;
y = rad;
drawCirclePoints (x,y,xc,yc);
d = 1 - rad;
while (x < y)
{
if (d < 0)
{x++;d += 2*x +1;}
else
{ x++; y--;d += 2*(x-y) + 1;}

drawCirclePoints (x,y,xc,yc);
}
}

Dan Bartlett
10-05-2012, 04:17 AM
What does your projection matrix look like?
Have you set it up something like this?

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (0, windowWidth, 0, windowHeight);

TalysShade
10-05-2012, 07:06 AM
That would be the following:


glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D (XMIN,
XMIN + (XMAX-XMIN) * ((GLdouble) w)/((GLdouble) WINSIZE_X),
YMIN,
YMIN + (YMAX-YMIN) * ((GLdouble) h)/((GLdouble) WINSIZE_Y));

Where XMIN and XMAX and so are -50 and 50 in user coordinates.

Dan Bartlett
10-05-2012, 02:20 PM
It depends on the effect you're after.

If you're trying to split the screen into a 100x100 grid where each point that forms the circle is clearly visible (eg. each point is 1/100th of the screen width), then OpenGL's point size isn't affected by transformations, so the points you draw will still be 1x1 pixel even after adjusting the projection matrix. If you want the points to appear larger, then you could try adjusting the point size (although points have size limit), or drawing quads/triangles instead of points:

glBegin(GL_QUADS); glVertex2i (xc+x,yc+y);
glVertex2i (xc+x+1,yc+y);
glVertex2i (xc+x+1,yc+y+1);
glVertex2i (xc+x,yc+y+1);
...

If you are after circles that are 1 pixel wide, then you would need to adjust the values you plug into the Bresenham algorithm to make sure you generate enough points for every pixel you want drawn. You could do this inside awCircle, or before you plug the values in. It would probably be easier if you used gluOrtho2D (0, windowWidth, 0, windowHeight) if you want to continue using glVertex2i, otherwise you will need to use glVertex2f to draw to the pixels that occur between the integer values.

TalysShade
10-05-2012, 02:42 PM
Hmm.. alright thank you. I was hoping there was a way to actually connect the dots, but I will have to try this. I have to continue using glVertex2i so I will try out your suggestion tomorrow. The user coordinates thing is just something I started out with for an example program so I really didn't know how to do it otherwise, I'll see what happens by changing gluOrtho2D to what you said, that might help a lot, cause that's something I was actually struggling with and didn't know it would be so easy to change.

Thanks for the help, I'll post whether it worked or not.

EDIT:

Couldn't resist trying right away. Simply changing gluOrtho2D did the trick to make nice lines instead of just dots. Thanks, learned a lot!