PDA

View Full Version : How to draw circle ?



openglfirst
01-08-2010, 09:57 AM
I want to draw a circle.
How would i do this?

Exoide
01-08-2010, 10:27 AM
Hi,

You must do it in the same way you draw a rectangle. You must calculate every point of the circle having the center's position and the radius and then draw it with GL_LINE_LOOP

here is the way I did it. I'm using TaoFramework and C#.

First I create the vertices for the circle and store them in a list. The circle will always be created at the origin of the coordinate system.



// Create the circle in the coordinates origin
for (int a = 0; a < 360; a += 360 / sides)
{
heading = a * MathEx.deg2Rad;
vertices.Add(new Vector3d(Math.Cos(heading) * this.radius, Math.Sin(heading) * this.radius, position.Z));
}


sides = the amount of segments the circle will have.

Now we can render it.



Gl.glBegin(Gl.GL_LINE_LOOP);
for (int i = 0; i < vertices.Count; i++)
Gl.glVertex3dv(vertices[i]);
Gl.glEnd();


I hope this help you.

openglfirst
01-08-2010, 10:31 AM
How to do that in C/C++ ?

Exoide
01-08-2010, 10:41 AM
How to do that in C/C++ ?


It's the same thing. You just need to remove the "Gl." at the beginning of each statement.



heading = a * MathEx.deg2Rad;

must be replaced with


heading = a * 3.1415926535897932384626433832795 / 180;

Vector3d can be declared as


struct Vector3d
{
double x, y, z;
};

and then create an array of it.

That's all.

openglfirst
01-08-2010, 10:53 AM
Is it possible to draw circle with "glVertex2i" function?

Exoide
01-08-2010, 11:10 AM
It's possible but if you want a better accurate circle you must use at least glVertex2f() because you have to do rotations that implies decimal values and using glVertex2i the decimals of the results will be truncated.

In the example the third item of the Vector3d can be removed. In fact the algorithm I showed you is to draw a circle in the XY plane so effectively you can use glVertex2f() or glVertex2d() and of course glVertex2i().

Here is a very simple sample in C



// Create the circle in the coordinates origin
const int sides = 20; // The amount of segment to create the circle
const double radius = 5; // The radius of the circle

glBegin(GL_LINE_LOOP);

for (int a = 0; a < 360; a += 360 / sides)
{
double heading = a * 3.1415926535897932384626433832795 / 180;
glVertex2d(cos(heading) * radius, sin(heading) * radius);
}

glEnd();

glFlush();

True_Name
01-09-2010, 07:58 AM
i want to draw multiple circles. For this, program should read position of the circle from file and then draw multiple circle.But i don't know how it would happen. Here is my code which draws 4 circles using a loop.....
can anyone help me regarding this...??

code....



#include <GL/glut.h>
#include<math.h>
#include <stdio.h>
//#include<stdlib.h>
//using namespace std;
int Height=400, Width=400;
void display(void)
{
/* clear all pixels */
glClear (GL_COLOR_BUFFER_BIT);

/* draw white polygon (rectangle) with corners at
* (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
*/



glColor3f (0.2, 0.9, 0.0);
float cosine=0.0,sine=0.0;
float center=0.5;
float x,y,m=0.0,n=0.0;


for(int i=1;i<5;i++)
{
::glPushMatrix();
//::glScalef( 2.5, 1.5, 0.5 );
::glTranslatef( i*0.2, i*0.2, 0.0 );
//::glRotatef( 10.0, 0.0, 0.0, 1.0 );

glBegin(GL_POLYGON);
for(int j=0;j<100;j++)
{
float angle = ((2*3.1415926535897*j)/100);

if(i==3)
{
m= -0.2;
n= -0.4;
x = m+cos(angle)/32;
y = n+sin(angle)/32;
}
else
{
x = (i/10)+cos(angle)/32;
y = (i/10)+sin(angle)/32;


}
glVertex2f(x,y);
}
glEnd();
::glPopMatrix();
}

/* don't wait!
* start processing buffered OpenGL routines
*/
glFlush ();


}
static void Reshape(int w, int h)
{
/*
glClear(GL_COLOR_BUFFER_BIT);

Width = w; Height = h;

glViewport (0, 0, Width, Height);

glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
glOrtho(-20.0*(GLfloat)w/(GLfloat)h,20.0*(GLfloat)w/(GLfloat)h, -20.0, 20.0, -20.0, 20.0);*/
////////////////////////
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/*if (w <= h)
glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w,
5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0);
else*/
glOrtho(-20.0*(GLfloat)w/(GLfloat)h,20.0*(GLfloat)w/(GLfloat)h, -20.0, 20.0, -20.0, 20.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
///////////////////////
}
void init (void)
{
/* select clearing color */
glClearColor (0.0, 0.0, 0.0, 0.0);

/* initialize viewing values */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}

/*
* Declare initial window size, position, and display mode

* (single buffer and RGBA). Open window with "hello"
* in its title bar. Call initialization routines.
* Register callback function to display graphics.
* Enter main loop and process events.
*/
int main(int argc, char** argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();
// glutReshapeFunc(Reshape);
glutDisplayFunc(display);
glutMainLoop();
return 0; /* ANSI C requires main to return int. */


}

MaxH
01-09-2010, 12:18 PM
Does this code actually compile?

If so, what happens when you run it?

True_Name
01-10-2010, 09:43 AM
yes it is..
It shows the 4 circles on different points.
This whole work is done by loop.
But i want to read values of x and y form files and the draw it.
But don't know the exact idea.

MaxH
01-10-2010, 01:17 PM
Sorry but this program does not compile for me. Maybe you are running a different version than what you posted? My compiler (Visual Studio) doesn't like the lines beginning with :: . If you post a version that compiles and runs, I'll try to help you. Could you post a screen grab showing the '4 circles'? When you post code, it would really help if you cleaned it up as much as possible and posted it within {code} and {/code} tags, which preserves the indentations. Except use square brackets instead of squiggly brackets around the words code. An example is included below of your main routine ...



int main (int argc, char** argv)
{
glutInit (&amp;argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("Circles");
init ();
glutDisplayFunc (display);
glutMainLoop ();

return 0;
}

True_Name
01-10-2010, 06:19 PM
I have also Microsoft visual studio 2005.




Code:

#include <GL/glut.h>
#include <math.h>
#include <stdio.h>

int Height=400, Width=400;
void display(void)
{

glClear (GL_COLOR_BUFFER_BIT);

/* draw white polygon (rectangle) with corners at
* (0.25, 0.25, 0.0) and (0.75, 0.75, 0.0)
*/



glColor3f (0.2, 0.9, 0.0);

float cosine=0.0,sine=0.0;
float center=0.5;
float x,y,m=0.0,n=0.0;
for(int i=1;i<5;i++)
{
glPushMatrix ();
glTranslatef ( i*0.2, i*0.2, 0.0 );
glBegin (GL_POLYGON);
for(int j=0;j<20;j++)
{
float angle = ((2*3.1415926535897*j)/20);

if(i==3)
{
m= -0.2;
n= -0.4;
x = m+cos(angle)/32;
y = n+sin(angle)/32;
}
else
{
x = (i/10)+cos(angle)/32;
y = (i/10)+sin(angle)/32;


}
glVertex2f(x,y);
}
glEnd();
glPopMatrix();
}

/* don't wait!
* start processing buffered OpenGL routines
*/
glFlush ();


}
static void Reshape(int w, int h)
{

glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-20.0*(GLfloat)w/(GLfloat)h,20.0*(GLfloat)w/(GLfloat)h, -20.0, 20.0, -20.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
///////////////////////
}
void init (void)
{

glClearColor (0.0, 0.0, 0.0, 0.0);


glMatrixMode (GL_PROJECTION);
glLoadIdentity ();

}


int main(int argc, char** argv)
{
glutInit (&amp;argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("hello");
init ();

glutDisplayFunc (display);
glutMainLoop ();
return 0;


}

MaxH
01-10-2010, 09:38 PM
That last version of your code was much cleaner. It ALMOST compiled on my PC. My compiler objected to the lines where you declared an 'int' inside a 'for' statement. After I fixed that, your program ran. So your OpenGL graphics works! I can help you a little by reorganizing your code to make it more suitable to your problem. I start with an global array (called 'dots') filled with 4 points . I draw the circles two ways: 1) as green, anti-aliased points, and 2) as orange polygons offset from the green dots. The dot-drawing approach is much simpler. If you get acceptable results with dots, I'd go that way. My PC at work (NVidia card) draws large dots as beautiful, smooth, circles. My my card at home (Radeon) doesn't do as good a job. Even though Point anti-aliasing is turned on, the dots aren't very smooth on my home computer. The second way the circles are drawn (in orange) is to pre-compute the vertex coordinates of a circle, then draw them as a single polygon. This results in smoother circles. The orange circles are drawn at different sizes to see how the smoothing is affected.

I know that I haven't totally solved your problem. You still have to read the center coordinates of the points out of a file and put them into a global array. But that isn't a graphics issue. It's a basic 'C' programming task.

http://www.mfwweb.com/OpenGL/Circles/Grab.JPG



// -----------------------------------------------------------------------------
// Two ways to draw OpenGL circles. MaxH - Jan 10, 2010

#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>

#define RADDEG 57.29577951

float circle [120][2], dots[4][2] = {{-10, -10}, {-10, 10}, {10, -3}, {10, 7}};

// -----------------------------------------------------------------------------

// Vector P is center of circle. r is radius.

void Big_Dot (float r, float *P)
{
glPointSize (r);
glBegin (GL_POINTS); glVertex2fv (P); glEnd();
}

// -----------------------------------------------------------------------------

void Unit_Circle (void)
{
int p;
float angle;
static short first = TRUE;

// Initialize unit circle array. Only done first time routine is called.

if (first) {
for (p = 0; p < 120; p++) {
angle = 3.0 * p / RADDEG;
circle[p][0] = cos (angle);
circle[p][1] = sin (angle);
}
first = FALSE;
}

// Draw circle as a single polygon.

glBegin (GL_POLYGON);
for (p = 0; p < 120; p++) glVertex2fv (circle[p]);
glEnd ();
}

// -----------------------------------------------------------------------------

void display (void)
{
p;
float x, y, s;

glMatrixMode (GL_PROJECTION);
glOrtho (-20.0, 20.0, -20.0, 20.0, -20.0, 20.0);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
glClear (GL_COLOR_BUFFER_BIT);

// Draw 4 green, circles using large, anti-aliased points.

glColor3f (0.2, 0.9, 0.0);
glEnable (GL_POINT_SMOOTH);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
for (p = 0; p < 4; p++) Big_Dot (15.0, dots[p]);
glDisable (GL_POINT_SMOOTH);

// Draw 4 orange, circles using a transformed unit circle.

glColor3f (0.9, 0.5, 0.1);
for (p = 0; p < 4; p++) {
x = dots[p][0] - 5;
y = dots[p][1] - 5;
s = (1.0 + (float)p) / 5.0;
glPushMatrix ();
glTranslatef (x, y, 0);
glScalef (s, s, 1);
Unit_Circle ();
glPopMatrix ();
}

glutSwapBuffers ();
}

// -----------------------------------------------------------------------------

int main (int argc, char** argv)
{
glutInit (&amp;argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("MaxH - Circles");
glutDisplayFunc (display);
glutMainLoop ();

return 1;
}

//------------------------------------------------------------------------------