【问题标题】:How to draw a tapered arc (curve with decreasing thickness) in OpenGL?如何在OpenGL中绘制锥形弧(厚度减小的曲线)?
【发布时间】:2013-08-15 04:21:00
【问题描述】:

我有以下代码来绘制任意弧:

void CenteredArc::drawPolygonArc(float radius, float thickness, float startAngle, float arcAngle) {
    float num_segments = 360.0;

    float radiusOuter = radius + thickness / 2;
    float radiusInner = radius - thickness / 2;
    float theta = arcAngle / num_segments; 
    float tangetial_factor = tanf(theta);//calculate the tangential factor 

    float radial_factor = cosf(theta);//calculate the radial factor 

    float xxOuter = radiusOuter * cosf(startAngle);
    float yyOuter = radiusOuter * sinf(startAngle);
    float xxInner = radiusInner * cosf(startAngle);
    float yyInner = radiusInner * sinf(startAngle);  

    float prevXXOuter = -1;
    float prevYYOuter = -1;
    float prevXXInner = -1;
    float prevYYInner = -1;

    glPolygonMode(GL_FRONT, GL_FILL);
    for(int ii = 0; ii < num_segments; ii++) 
    { 
        if (prevXXOuter != -1) {
            glBegin(GL_POLYGON);
                glVertex2f(prevXXOuter, prevYYOuter);
                glVertex2f(xxOuter,     yyOuter);
                glVertex2f(xxInner,     yyInner);
                glVertex2f(prevXXInner, prevYYInner);
            glEnd();
        }

        //calculate the tangential vector 
        //remember, the radial vector is (x, y) 
        //to get the tangential vector we flip those coordinates and negate one of them 

        float txOuter = -yyOuter; 
        float tyOuter =  xxOuter; 
        float txInner = -yyInner; 
        float tyInner =  xxInner; 

        //add the tangential vector 

        prevXXOuter = xxOuter;
        prevYYOuter = yyOuter;
        prevXXInner = xxInner;
        prevYYInner = yyInner;

        xxOuter += txOuter * tangetial_factor; 
        yyOuter += tyOuter * tangetial_factor; 
        xxInner += txInner * tangetial_factor; 
        yyInner += tyInner * tangetial_factor; 

        //correct using the radial factor 
        xxOuter *= radial_factor; 
        yyOuter *= radial_factor; 
        xxInner *= radial_factor; 
        yyInner *= radial_factor; 
    }
}

但是,我希望弧从一端指定的厚度开始,然后逐渐减小到另一端的厚度为零。有什么建议吗?

编辑:我没有使用GL_LINE_STRIP,因为我试图避免出现这样的重叠线条和间隙:

【问题讨论】:

    标签: c++ opengl graphics geometric-arc


    【解决方案1】:

    我会使用 line strip 并减少 glLineWidth

    这是我的实现,它不会逐渐减少lineWidth,但可以对其进行修改。抱歉,多余的东西来自我的游戏引擎。

    for(int i=0;i<arcs().size();i++)
    {
            Entities::Arc temp = arcs().at(i);
            glLineWidth(temp.LW.value); // change LWidth
    
            glColor3f( temp.CL.R, temp.CL.G, temp.CL.B );
    
            // theta is now calculated from the arc angle instead, the
            // - 1 part comes from the fact that the arc is open
            float theta = temp.A.value*DEG2RAD / float(WW_SPLINE_ACCURACY - 1);
    
            float tan = tanf(theta);
            float cos = cosf(theta);
    
            // we are now at the starting angle
            double x = temp.R.value * cosf(temp.A.value*DEG2RAD);
            double y = temp.R.value * sinf(temp.A.value*DEG2RAD);
    
            // since the arc is not a closed curve, this is a strip now
            glBegin(GL_LINE_STRIP);
            for(int ii = 0; ii < WW_SPLINE_ACCURACY; ii++)
            {
                glVertex2d(x + temp.C.X, y + temp.C.Y);
                double tx = -y;
                double ty = x;
                x += tx * tan;
                y += ty * tan;
                x *= cos;
                y *= cos; //y = ( y + (ty*tan) )*cos;
            }
        glEnd();
        glLineWidth(WW_DEFAULT_LWIDTH); // reset LWidth
    }
    

    我也使用了这些值

    #define WW_SPLINE_ACCURACY  72 // 72 for extra smooth arcs/circles, 32 minimum
    #define WW_BEZIER_ACCURACY  20
    
    /* Math stuff */
    #define DEG2RAD 3.14159/180
    #define PI  3.1415926535897932384626433832795;
    
    ...
    
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_COLOR_MATERIAL);
    glEnable (GL_LINE_SMOOTH);
    glEnable (GL_BLEND);
    //glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glHint (GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
    glEnable(GL_POLYGON_SMOOTH);
    glClearColor(0.188f, 0.169f, 0.329f, 1.0f); //#302b54
    

    因为我是为一家公司写的,所以我不允许发布完整的源代码,但分享一两部分不会伤害任何人:D

    【讨论】:

    • 什么是WW_SPLINE_ACCURACY
    • @vulpix 是一个常数,控制每条弧线将使用多少个顶点!
    • 我没有使用GL_LINE_STRIP 而是绘制多边形的原因是因为超过 5 像素左右的厚度后渲染看起来不太好。您可以看到外边缘缺少条子。
    • 对,但是你把它设置成什么值?
    • 愚蠢的 SO 正在恢复我的编辑!!该值是 72 以获得额外的平滑度和 32 最小值。
    猜你喜欢
    • 2014-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多