【问题标题】:Effecient way to draw Ellipse with OpenGL or D3D使用 OpenGL 或 D3D 绘制椭圆的有效方法
【发布时间】:2011-05-04 16:23:56
【问题描述】:

有一种快速的方法可以像这样画圆

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

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

【问题讨论】:

  • 只要您使用立即模式(glBegin、glVertex、glEnd 等),该代码就永远不会“高效”

标签: opengl graphics vector geometry


【解决方案1】:

如果我们以您为例,我们可以使用 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(); 
}

【讨论】:

    【解决方案2】:

    openGL没有办法画曲线,只能画很多直线。但是如果你使用顶点缓冲对象,那么你就不必将每个顶点都发送到显卡上,这样会快得多。

    My Java Example

    【讨论】:

      【解决方案3】:

      如果椭圆为 ((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 的 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 轴对齐时才有效(如果即便如此?)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-10
      • 1970-01-01
      相关资源
      最近更新 更多