使用OpenGL或D3D绘制椭圆的高效方法

3
有一种快速的方法可以画出这样的圆形。
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(); 
}

我想知道是否有一种类似的方法可以绘制椭圆,其中其长轴/短轴向量和大小都已知。


1
只要你使用即时模式(glBegin,glVertex,glEnd等),那段代码将永远不会"高效"。 - Axel Gneiting
3个回答

8
如果我们采用您的例子,我们可以使用内部半径为1,并分别应用水平/垂直半径,以获得一个椭圆形:

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

4

在OpenGL中没有办法画出曲线,只能用很多条直线来拼凑。但是如果你使用了顶点缓冲对象,那么就不必将每个顶点发送到显卡,这样会更快。

我的Java示例


1

如果椭圆是 ((x-cx)/a)^2 + ((y-cy)/b)^2 = 1,那么将glVertex2f调用更改为glVertext2d(a*x + cx, b*y + cy)。

为了简化计算,让我们假设一段时间内椭圆位于原点。

如果将椭圆旋转,使得半长轴(长度为a)与x轴成角度θ,则椭圆是点p的集合,使得p' * inv(C) * p = 1,其中C是矩阵R(theta) * D * R(theta)',其中'表示转置,D是对角线元素为a*a,b*b(b为半短轴长度)的对角矩阵。如果L是C的Cholesky分解因子(例如here),则椭圆是点p的集合,使得(inv(L) * p)'*(inv(L) *p ) = 1,因此L将单位圆映射到椭圆上。如果我们已经计算出L为(u 0; v w)(在循环之前只需计算一次),则glVertexf调用变为glVertex2f(u*x + cx, v*x + w*y + cy)。

可以按照以下方式计算 L (其中 C 为 cos(theta),S 为 sin(theta)):

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


我认为这仅在椭圆轴与X轴和Y轴对齐时才有效(即使是这样也不确定)。 - LarsH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接