Effecient way to draw Ellipse with OpenGL or D3D
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.
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;
giggle
Updated on January 12, 2020Comments
-
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 about 13 yearsI think this only works when the ellipse axes are aligned to the X and Y axes (if even then?).