Effecient way to draw Ellipse with OpenGL or D3D

22,803

Solution 1

There is no way to draw a curve in openGL, just a lot of straight lines. But if you used vertex buffer objects then you won't have to send each vertex to the graphics card which will be much faster.

My Java Example

Solution 2

If we take your example we can use an internal radius of 1 and apply horizontal/vertical radius separately in order to get an ellipse:

void DrawEllipse(float cx, float cy, float rx, float ry, 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 = 1;//we start at angle = 0 
    float y = 0; 

    glBegin(GL_LINE_LOOP); 
    for(int ii = 0; ii < num_segments; ii++) 
    { 
        //apply radius and offset
        glVertex2f(x * rx + cx, y * ry + cy);//output vertex 

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

Solution 3

If the ellipse is ((x-cx)/a)^2 + ((y-cy)/b)^2 = 1 then change the glVertex2f call to glVertext2d(a*x + cx, b*y + cy);

To simplify the sums, lets suppose for a while that the ellipse is centred at the origin.

If the ellipse is rotated so that the semi-major axis (of length a) makes an angle theta with the x axis, then the ellipse is the set of points p so that p' * inv(C) * p = 1, where C is the matrix R(theta) * D * R(theta)' where ' denotes transpose and D is the diagonal matrix with entries a*a,b*b (b the length of the semi-minor axis). If L is the cholesky factor (eg here) of C then the ellipse is the set of points p so that (inv(L) * p)'*(inv(L) *p ) = 1, so that L maps the unit circle to the ellipse. If we have computed L as ( u 0 ; v w) (just once, before the loop) then the glVertexf call becomes glVertex2f( u*x + cx, v*x + w*y + cy);

L can be calculated like this (where C is cos(theta) and S is sin(theta)):

u = sqrt( C*C*a*a + S*S*b*b); v = C*S*(a*a-b*b); w = a*b/u;

Share:
22,803
giggle
Author by

giggle

Updated on January 12, 2020

Comments

  • giggle
    giggle over 4 years

    There is a fast way to draw circle like this

    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(); 
    }
    

    I am wondering if there is a similar way to draw ellipse where its major/minor axes vector and size are both known.

  • LarsH
    LarsH about 13 years
    I think this only works when the ellipse axes are aligned to the X and Y axes (if even then?).