从弧边绘制曲线 [英] Draw a curved line from an arc edge

查看:191
本文介绍了从弧边绘制曲线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在做什么的屏幕截图。目前,我无法在此矩形中绘制弯曲的边框。

Here's the screenshot of what I am doing. Currently, I'm stuck from drawing a curved borders into this rectangle.

我的第一个解决方案是:在矩形后面绘制一个四分圆,但是如果我调整形状的不透明度,

My first solution was: draw a quartered circle behind the rectangle, but if I adjust the opacity of the shape, as you can see, the quartered circle gets shown.

我知道这对你们来说是很基本的,但我不是真的擅长数学。

I know this is pretty basic for you guys but I'm not really good at math.

我尝试重复使用计算出的弧的边缘并添加边框的大小,但我得到了结果。

I did try to reuse the computed edges of the arc and add the size of border but I got this as a result.

我也认为of bezier curves 作为替换,但我认为只是重用计算的顶点和添加所有丢失的顶点更有效。此外,我不知道如何计算曲线的弯曲点,并且找到正确的 t 的金额将是非常计算昂贵的我不实现它。

I also think of bezier curves as a replacement but I think it is more efficient to just reuse the computed vertices and add all the missing ones. Also, I don't know how to compute for the curved points of bezier curves and finding the right amount of t would be very computationally expensive so I don't implement it.

下面是我如何绘制内部四分圆的代码,我想我可以重用它。 p>

Here's the code how I draw the inner quartered circle and I think I can just reuse it.

void drawArc(int x, int y,
             int startAngle, int endAngle,
             uint32_t radiusX, uint32_t radiusY,
             int border_x, int border_y,
             const rgb color,
             const rgb bcX, const rgb bcY,
             uint8_t opacity)
{
    if (radiusX <= 0 || radiusY <= 0) return;

    static constexpr float DTR = 3.14159 / 180;

    float cx, cy;
    int step;

    static std::vector<float> verts;
    static std::vector<uint8_t> colors;

    if (startAngle < endAngle)
    {
        step = +1;
        ++ endAngle;
    } else
    {
        step = -1;
        -- endAngle;
    }

    verts.clear();
    colors.clear();

    verts.push_back(x);
    verts.push_back(y);

    colors.push_back(color[R]);
    colors.push_back(color[G]);
    colors.push_back(color[B]);
    colors.push_back(opacity);

    while (startAngle != endAngle)
    {
        cx = cos(DTR * startAngle) * radiusX;
        cy = sin(DTR * startAngle) * radiusY;

        verts.push_back(x + cx);
        verts.push_back(y - cy);

        colors.push_back(color[R]);
        colors.push_back(color[G]);
        colors.push_back(color[B]);
        colors.push_back(opacity);

        startAngle += step;
    }

    drawElements(GL_POLYGON, sizeof(arcIndices) / sizeof(arcIndices[0]), GL_FLOAT,
                 &verts[0], &colors[0], &arcIndices[0]);

    if (border_x != 0 || border_y != 0)
    {
        //remove (x, y)
        verts.erase(verts.begin(), verts.begin() + 2);

//        float px, py;
//
//        px = *(verts.begin() + 0);
//        py = *(verts.begin() + 1);
//
//        glPointSize(5);
//
//        glBegin(GL_POINTS);
//
//        glColor3ub(0,0,255);
//        glVertex2i(px, py);
//
//        px = *(verts.end() - 2);
//        py = *(verts.end() - 1);
//
//        glColor3ub(255,0,0);
//        glVertex2i(px , py);
//        glEnd();

        //attempting to reuse the edges
        //I think the last vertices are opposed
        //that's why I got a crossed out lines??
        for (int i = 0;i <= 90; ++i)
        {
            verts.push_back(verts[i + 0] + border_x);
            verts.push_back(verts[i + 1] + border_y);

            colors.push_back(bcX[R]);
            colors.push_back(bcX[G]);
            colors.push_back(bcX[B]);
            colors.push_back(opacity);
        }

        //91 = steps from 0-90 degree revolution
        //182 = 91 * 2
        unsigned int index[182 + 91 * 2];
        for (int i = 0;i < 182 + 91 * 2; ++i)
            index[i] = i;

        drawElements(GL_LINE_LOOP, verts.size() / 2, GL_FLOAT,
                    &verts[0], &colors[0], &index[0]);
    }

}

strong>

我以前不能重复使用预先计算的(x,y)?

Can't I just reuse the pre-calculated (x,y) before?

img src =http://i.stack.imgur.com/aSMgT.pngalt =nooh>

对不起,太多使用图片

Sorry for too much use of pictures

红点是预先计算的(x,y)我指的是并且只是附加下一个圆弧基础。

The red dots are pre-calculated (x, y) I'm referring to and just append the next arc base on this.

我要渲染许多这样的东西,所以我需要尽可能高效(w / o太多用于trigo函数)。

I'm gonna render many of this kind so I need as efficient as possible(w/o too much use to trigo functions).

更新:

下面是使用 stencil buffer 为什么 Andon M. Coleman 建议:

And here is the result I got from using stencil buffer as what Andon M. Coleman suggested:

Btw可以看到,我试图模仿我自己的UI使用OpenGL:D

Btw, as you can see, I am trying to emulate my own UI using OpenGL :D

推荐答案

你表示有兴趣看看这可能如何解决使用模板缓冲器昨天,所以我跟进一些基本的伪代码。

You expressed an interest in seeing how this could be solved using the stencil buffer yesterday, so I am following up with some basic pseudo-code.

glClearStencil (0x0);
glClear        (GL_STENCIL_BUFFER_BIT);

glEnable       (GL_STENCIL_TEST);
glStencilFunc  (GL_ALWAYS, 0x0, 0x0);

// Add 1 to stencil buffer at every location the object to be bordered is visible
glStencilOp    (GL_KEEP, GL_KEEP, GL_INCR);

// Draw your grey object

// Only draw the red border where the grey object was never drawn (stencil = 0x0)
glStencilFunc  (GL_EQUAL, 0x0, 0xff);

// Draw your red quarter circles

glDisable     (GL_STENCIL_TEST);

每次绘制轮廓对象时清除模板缓冲区可能是过度的。如果你选择每帧清除模板缓冲区一次,你可以做一些很有趣的事情。例如,如果在绘制所有非轮廓形状之后将轮廓绘制为单独的轮廓,则可以使用此模板缓冲区设置来勾勒 交叉的对象作为绘制轮廓的一部分)任何重叠的对象。这将允许你从你简单的圆角矩形构造更复杂的形状。

Clearing the stencil buffer everytime you draw your outlined object is probably overkill. If you opt to clear the stencil buffer once per-frame instead, you can do some pretty interesting things. For instance, if you drew the outlines as a separate pass after all non-outlined shapes are drawn you could use this stencil buffer setup to outline the union (instead of including the intersection of objects as part of the drawn outline) of any overlapping objects.. this would allow you to construct more complicated shapes from your simple rounded rectangles.

要工作,您的像素格式必须有一个模板缓冲区。我必须把这部分留给你,因为设置它的过程是具体的实现。

Of course for this to work, your pixel format must have a stencil buffer. I will have to leave that part up to you, because the process of setting that up is implementation specific.

这篇关于从弧边绘制曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆