# Arcs and Circles

Hi,
I have to draw circles and arcs in fill mode as well as connected line loops. For filled arcs and circles, i am using gludisk and glupartialdisk and its working fine. The arcs and circles have width. so for drawing them as connected line loops how to draw…? Only the outline should be there with the specified width. And also i have to draw arcs and circles with no width. Can i use bezier curve to do this…? If so, how can i do.? Please help me…

No, don’t use beizer curve - use LINE_STRIP or TRIANGLE_STRIP and compute vertex coordinates yourself: sin(angle)*radius, cos(angle)*radius
When using LINE_STRIP you can manipulate the line width, and when using TRIANGLE_STRIP you just pass coordinates of inner and outer edge.

For filled polygons,
The coding is,

``````	glPushMatrix();

glTranslatef(XCen, YCen, 0.0);
glTranslatef(-XCen, -YCen, 0.0);

glPopMatrix();

``````

Without width and not as a filled arc,

The coding is,

``````    glBegin(GL_TRIANGLE_STRIP);

for(i = startang; i <= endang; i+=10)
{
GLfloat ang = (GLfloat) (i * M_PI);
glVertex2f((float) (XCenter + cos(ang) * (radius1)), (float) (YCenter + sin(ang) * (radius1)));
}

``````

But for Circle and arc with width, and not as filled one, how to write the statements…?

``````float radius1 = radius - width / 2;
glBegin(GL_TRIANGLE_STRIP);
for(i = startang; i <= endang; i+=10)
{
GLfloat ang = (GLfloat) (i * M_PI);
glVertex2f((float) (XCenter + cos(ang) * (radius1)), (float) (YCenter + sin(ang) * (radius1)));
glVertex2f((float) (XCenter + cos(ang) * (radius2)), (float) (YCenter + sin(ang) * (radius2)));
}
glEnd();
``````

Hi k_szczech,

``   Thank you a lot. Its working fine. But its coming as a filled arc. I want the arc to be not filled. Sorry if my doubt is so basic.``

Is this what you want?

``````float radius1 = radius - width / 2;
glBegin(GL_LINE_LOOP);
for(i = startang; i <= endang; i+=10)
{
GLfloat ang = (GLfloat) (i * M_PI);
glVertex2f((float) (XCenter + cos(ang) * (radius1)), (float) (YCenter + sin(ang) * (radius1)));
}
for(i = endang; i >= startang; i-=10)
{
GLfloat ang = (GLfloat) (i * M_PI);
glVertex2f((float) (XCenter + cos(ang) * (radius2)), (float) (YCenter + sin(ang) * (radius2)));
}
glEnd();
``````

Yeah, thats it… Thank you. Its working fine. One more thing. Sorry for continuous questions. I am drawing complex polygons using tesselation. Its coming very well as filled polygons. The shape is correct. But i have to draw them also as connected line loops instead of filled polygons. For that, I am using glBegin(which) in begincallback function. So its rendered as a filled polygon correctly. But to draw them as connected line loops, i just gave as glBegin(GL_LINE_LOOP), but the shape is incorrect.

``````    I could understand why this happens. The thing is,
``````
1. I will call begincallback function
2. Then, i will pass all the vertices
3. At last, call endcallback function
4. So only after all the vertex have been gotten
its looking for the unwanted ones and
neglecting them.
Thats why, if i gave GL_LINE_LOOP, it just drawing connected lines to all the vertices i have passed. And while drawing like this, it is no more a polygon… Just a irregular one… Help me in this…
``````GLUtesselator *tobj;
tobj = gluNewTess();

gm_VertexPtrList = new CPtrList();

int templine;

gluTessCallback(tobj, GLU_TESS_BEGIN, (void (CALLBACK *) ())beginCallback);
gluTessCallback(tobj, GLU_TESS_VERTEX, (void (CALLBACK *) ()) vertexCallback);
gluTessCallback(tobj, GLU_TESS_END, (void (CALLBACK *) ())endCallback);
gluTessCallback(tobj, GLU_TESS_ERROR,(void (CALLBACK *) ())errorCallback);
gluTessCallback(tobj, GLU_TESS_COMBINE, (void (CALLBACK *) ())combineCallback);

gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
gluTessNormal(tobj, 0, 0, 1);
gluTessBeginPolygon(tobj, NULL);
gluTessBeginContour(tobj);

pVertex = new GLdouble[3];
pVertex[0] = XStartpt;
pVertex[1] = YStartpt;
pVertex[2] = 0.0;

gluTessVertex(tobj, pVertex, pVertex);

templine = 1;

noofpts = noofpts - 1;

for(int incvar1 = 0; incvar1 < noofpts; incvar1++)
{

OutlinePoints* outpts = (OutlinePoints*) outlinemacro -> Outline_Points.GetAt(incvar1);

XPoint = (GLfloat) (outpts -> XPoint);
YPoint = (GLfloat) (outpts -> YPoint);

XStartpt = XStart2 + XPoint;
YStartpt = YStart2 + YPoint;

pVertex = new GLdouble[3];
pVertex[0] = XStartpt;
pVertex[1] = YStartpt;
pVertex[2] = 0.0;

gluTessVertex(tobj, pVertex, pVertex);

templine++;

}

gluTessEndContour(tobj);
gluTessEndPolygon(tobj);
gluDeleteTess(tobj);

while( gm_VertexPtrList -> GetCount() > 0 )
{

GLdouble* pV  =  (GLdouble*)gm_VertexPtrList -> RemoveHead() ;
delete[] pV ;

pV = NULL ;

}

}

glPopMatrix();

delete[] pVertex;
pVertex = NULL;

}

void CALLBACK beginCallback(GLenum which)
{

glBegin(which);

}

void CALLBACK errorCallback(GLenum errorCode)
{

const GLubyte *estring;

estring = gluErrorString(errorCode);
fprintf(stderr, "Tessellation Error: %s
", estring);
exit(0);

}

void CALLBACK CDocumentationView :: endCallback(void)
{

glEnd();

}

void CALLBACK  vertexCallback(GLvoid *vertex)
{

GLdouble *pointer;

pointer = (GLdouble *) vertex;
//	glColor3dv(pointer+3);
glVertex3dv(pointer);

}

//static memvar used to keep track of newly allocated vertices

void CALLBACK  combineCallback(GLdouble coords[3],
GLdouble *vertex_data[4],
GLfloat weight[4], GLdouble **dataOut )
{

GLdouble *vertex = new GLdouble[3] ;

gm_VertexPtrList->AddTail( vertex ) ; //keep track for later delete[] at bottom of CMFCTessView::OnDraw()

vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = 0.0;
//01/13/05 bugfix

*dataOut = vertex;

}
``````

The code will look like this…

I’ve never used GLU’s tesselation, but if you just want an outline of a complex polygon then don’t use tesselation - simply use GL_LINE_LOOP and pass all polygon vertices. You only need tesselation for filled polygons.

Yeah, Its working… Thank you a lot k_szczech. I solved all my problems related to this… Thank you very much…

With lots of thanks,
Sangeetha.