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

Efficient way to draw Ellipse with OpenGL or D3D

本文关键字:有效 方法 绘制 OpenGL D3D 使用      更新时间:2023-10-16

有这样画圆的快速方法

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 的内部半径并分别应用水平/垂直半径以获得椭圆:

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

在openGL中没有办法画曲线,只有很多直线。 但是,如果您使用顶点缓冲区对象,则不必将每个顶点发送到图形卡,这将更快。

我的爪哇示例

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

为了简化总和,让我们假设椭圆以原点为中心。

如果旋转椭圆,使半长轴(长度为 a)与 x 轴形成一个角度 theta,则椭圆是点 p 的集合,因此 p' * inv(C) * p = 1,其中 C 是矩阵 R(theta) * D * R(theta)' 其中 ' 表示转置,D 是条目为 a*a 的对角矩阵,b*b(b 半短轴的长度)。如果 L 是 C 的胆碱因子(例如这里),则椭圆是点 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;