0

I want to iteratively draw line segments between N points where N is at least 100, for smoothness sake.

I want these segments to form a circle.

How do I calculate these points? OpenGL examples appreciated.

quantumpotato
  • 9,637
  • 14
  • 70
  • 146
  • Here's an answer with code for a filled circle, but it should be easy to modify it to draw an outline instead: http://stackoverflow.com/a/25321141/3530129. – Reto Koradi Dec 17 '14 at 05:20

1 Answers1

0

There's always the SiegeLord way:

void DrawCircle(float cx, float cy, float r, int num_segments) 
{ 
    float theta = 2 * 3.1415926 / float(num_segments); 
    float c = cosf(theta);//precalculate the sine and cosine
    float s = sinf(theta);
    float t;

    float x = r;//we start at angle = 0 
    float y = 0; 

    glBegin(GL_LINE_LOOP); 
    for(int ii = 0; ii < num_segments; ii++) 
    { 
        glVertex2f(x + cx, y + cy);//output vertex 

        //apply the rotation matrix
        t = x;
        x = c * x - s * y;
        y = s * t + c * y;
    } 
    glEnd(); 
}

All together:

#include <GL/glut.h>
#include <cmath>

void DrawCircle( float radius, float error ) 
{ 
    const float theta = acos( 1 - ( error / radius ) );
    const unsigned int num_segments = ( 2 * 3.1415926 ) / theta;

    //precalculate the sine and cosine
    const float c = cos( theta );
    const float s = sin( theta );

    //we start at angle = 0 
    float x = radius;
    float y = 0; 

    glBegin(GL_LINE_LOOP); 
    for( unsigned int i = 0; i < num_segments; i++ ) 
    { 
        glVertex2f( x, y );

        //apply the rotation matrix
        const float t = x;
        x = c * x - s * y;
        y = s * t + c * y;
    } 
    glEnd(); 
}

float radius = 50;
float direction = 1;
void timer( int extra )
{
    if( radius < 50 && direction == -1 )
        direction = 1;
    if( radius > 250 && direction == 1 )
        direction = -1;

    radius += 1 * direction;

    glutPostRedisplay();
    glutTimerFunc( 16, timer, 0 );
}

void display(void)
{
    glClear( GL_COLOR_BUFFER_BIT );

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    const double w = glutGet( GLUT_WINDOW_WIDTH );
    const double h = glutGet( GLUT_WINDOW_HEIGHT );
    glOrtho( -w/2, w/2, -h/2, h/2, -1, 1 );

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glColor3ub( 255, 255, 255 );
    DrawCircle( radius, 1 );

    glutSwapBuffers();
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
    glutInitWindowSize( 800, 600 );
    glutCreateWindow( "GLUT" );
    glutDisplayFunc( display );
    glutTimerFunc( 0, timer, 0 );
    glutMainLoop();
    return 0;
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • 1
    Somebody claimed ownership for this approach in 2006? That's funny. This solution is much older. Here's code I first wrote in 1994 (at least that's the copyright date, it's most likely older) using this, and it seemed so obvious that I very much doubt I was the first one: http://sourceforge.net/p/molmol/code/ci/Macintosh/tree/src/sg/src/def/DefCircle.c – Reto Koradi Dec 17 '14 at 05:38
  • 1
    @RetoKoradi: Elegant, not-the-first-thing-to-come-to-mind, but in retrospect obvious things get rediscovered and reinvented all the time. Happened to me as well, when I rediscovered a way to re-write a function testing a number for being a power-of-2 into a type agnostic C macro that doesn't require compiler specific extensions. I was so proud, only to find out that decades ago the very same macro was already published. Nevertheless I figured that thing out by myself. – datenwolf Dec 17 '14 at 07:53
  • @datenwolf True. I thought the standard power-of-2 test was attributed to Donald Knuth, but a search suggests that it's even older (1960). One of my first attempts at graphics was a line drawing algorithm in assembly that I implemented in high school. Turned out later that I had re-invented the Bresenham algorithm. – Reto Koradi Dec 17 '14 at 08:17