程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了OpenGL ES的多边形三角剖分成三角形带大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决OpenGL ES的多边形三角剖分成三角形带?

开发过程中遇到OpenGL ES的多边形三角剖分成三角形带的问题如何解决?下面主要结合日常开发的经验,给出你关于OpenGL ES的多边形三角剖分成三角形带的解决方法建议,希望对你解决OpenGL ES的多边形三角剖分成三角形带有所启发或帮助;

在2D且无孔的情况下,这相当容易。首先,您需要将多边形分解为一个或多个单调多边形。

单调多边形很容易变成三条纹,只需将值排序为y,找到最顶部和最底部的顶点,然后您就可以在左右两边找到顶点列表(因为顶点已定义,顺时针说)。然后,从最顶部的顶点开始,并从左侧和右侧以交替方式添加顶点。

此技术适用于任何不具有自相交边的2D多边形,其中包括某些情况下带有孔的多边形(但必须正确缠绕孔)。

您可以尝试使用以下代码:

glMatrixMode(GL_projection);
glLoadIDentity();
glMatrixMode(GL_MODELVIEW);
glLoadIDentity();
glTranslatef(-.5f, -.5f, 0);

std::vector<Vector2f> my_polygon;

my_polygon.push_BACk(Vector2f(-0.300475f, 0.862924f));
my_polygon.push_BACk(Vector2f(0.302850f, 1.265013f));
my_polygon.push_BACk(Vector2f(0.811164f, 1.437337f));
my_polygon.push_BACk(Vector2f(1.001188f, 1.071802f));
my_polygon.push_BACk(Vector2f(0.692399f, 0.936031f));
my_polygon.push_BACk(Vector2f(0.934679f, 0.622715f));
my_polygon.push_BACk(Vector2f(0.644893f, 0.408616f));
my_polygon.push_BACk(Vector2f(0.592637f, 0.753264f));
my_polygon.push_BACk(Vector2f(0.269596f, 0.278068f));
my_polygon.push_BACk(Vector2f(0.996437f, -0.092689f));
my_polygon.push_BACk(Vector2f(0.735154f, -0.338120f));
my_polygon.push_BACk(Vector2f(0.112827f, 0.079634f));
my_polygon.push_BACk(Vector2f(-0.167458f, 0.330287f));
my_polygon.push_BACk(Vector2f(0.008314f, 0.664491f));
my_polygon.push_BACk(Vector2f(0.393112f, 1.040470f));
// from wiki (http://en.wikipedia.org/wiki/file:polygon-to-monotone.png)

glEnable(GL_POINT_SMOOTH);
glEnable(GL_liNE_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_Alpha, GL_ONE_MINUS_SRC_Alpha);

gllinewidth(6);
glcolor3f(1, 1, 1);
glBegin(GL_liNE_LOOp);
for(size_t i = 0, n = my_polygon.size(); i < n; ++ i)
    glVertex2f(my_polygon[i].x, my_polygon[i].y);
glEnd();
glPointSize(6);
glBegin(GL_POINTS);
for(size_t i = 0, n = my_polygon.size(); i < n; ++ i)
    glVertex2f(my_polygon[i].x, my_polygon[i].y);
glEnd();
// draw the original polygon

std::vector<int> working_set;
for(size_t i = 0, n = my_polygon.size(); i < n; ++ i)
    working_set.push_BACk(i);
_ASSERTE(working_set.size() == my_polygon.size());
// add vertex inDices to the List (Could be done using iota)

std::List<std::vector<int> > monotone_poly_List;
// List of monotone polygons (the output)

glPointSize(14);
gllinewidth(4);
// prepare to draw split points and slice lines

for(;;) {
    std::vector<int> sorted_vertex_List;
    {
        for(size_t i = 0, n = working_set.size(); i < n; ++ i)
            sorted_vertex_List.push_BACk(i);
        _ASSERTE(working_set.size() == working_set.size());
        // add vertex inDices to the List (Could be done using iota)

        for(;;) {
            bool b_change = false;

            for(size_t i = 1, n = sorted_vertex_List.size(); i < n; ++ i) {
                int a = sorted_vertex_List[i - 1];
                int b = sorted_vertex_List[i];
                if(my_polygon[working_set[a]].y < my_polygon[working_set[b]].y) {
                    std::swap(sorted_vertex_List[i - 1], sorted_vertex_List[i]);
                    b_change = true;
                }
            }

            if(!b_changE)
                break;
        }
        // sort vertex inDices by the y coordinate
        // (note this is using bubblesort to maintain portability
        // but it should be done using a better sorTing method)
    }
    // build sorted vertex List

    bool b_change = false;
    for(size_t i = 0, n = sorted_vertex_List.size(), m = working_set.size(); i < n; ++ i) {
        int n_ith = sorted_vertex_List[i];
        Vector2f ith = my_polygon[working_set[n_ith]];
        Vector2f prev = my_polygon[working_set[(n_ith + m - 1) % m]];
        Vector2f next = my_polygon[working_set[(n_ith + 1) % m]];
        // get point in the List, and get it's neighbours
        // (neighbours are not in sorted List ordering
        // but in the original polygon order)

        float sIDePrev = sign(ith.y - prev.y);
        float sIDeNext = sign(ith.y - next.y);
        // calculate which sIDe they lIE on
        // (sign function gives -1 for negative and 1 for positive argument)

        if(sIDePrev * sIDeNext >= 0) { // if they are both on the same sIDe
            glcolor3f(1, 0, 0);
            glBegin(GL_POINTS);
            glVertex2f(ith.x, ith.y);
            glEnd();
            // marks points whose neighbours are both on the same sIDe (split points)

            int n_next = -1;
            if(sIDePrev + sIDeNext > 0) {
                if(i > 0)
                    n_next = sorted_vertex_List[i - 1];
                // get the next vertex above it
            } else {
                if(i + 1 < n)
                    n_next = sorted_vertex_List[i + 1];
                // get the next vertex below it
            }
            // this is kind of simpListic, one needs to check if
            // a line between n_ith and n_next doesn't exit the polygon
            // (but that doesn't happen in the examplE)

            if(n_next != -1) {
                glcolor3f(0, 1, 0);
                glBegin(GL_POINTS);
                glVertex2f(my_polygon[working_set[n_next]].x, my_polygon[working_set[n_next]].y);
                glEnd();
                glBegin(GL_lines);
                glVertex2f(ith.x, ith.y);
                glVertex2f(my_polygon[working_set[n_next]].x, my_polygon[working_set[n_next]].y);
                glEnd();

                std::vector<int> poly, remove_List;

                int n_last = n_ith;
                if(n_last > n_next)
                    std::swap(n_last, n_next);
                int idx = n_next;
                poly.push_BACk(working_set[IDx]); // add n_next
                for(IDx = (IDx + 1) % m; IDx != n_last; IDx = (IDx + 1) % m) {
                    poly.push_BACk(working_set[IDx]);
                    // add it to the polygon

                    remove_List.push_BACk(IDX);
                    // mark this vertex to be erased from the working set
                }
                poly.push_BACk(working_set[IDx]); // add n_ith
                // build a new monotone polygon by cutTing the original one

                std::sort(remove_List.begin(), remove_List.end());
                for(size_t i = remove_List.size(); i > 0; -- i) {
                    int n_which = remove_List[i - 1];
                    working_set.erase(working_set.begin() + n_which);
                }
                // sort inDices of vertices to be removed and remove them
                // from the working set (have to do it in reverse order)

                monotone_poly_List.push_BACk(poly);
                // add it to the List

                b_change = true;

                break;
                // the polygon was sliced, restart the algorithm, regenerate sorted List and slice again
            }
        }
    }

    if(!b_changE)
        break;
    // no moves
}

if(!working_set.empty())
    monotone_poly_List.push_BACk(working_set);
// use the remaining vertices (which the algorithm was unable to slicE) as the last polygon

std::List<std::vector<int> >::const_iterator p_mono_poly = monotone_poly_List.begin();
for(; p_mono_poly != monotone_poly_List.end(); ++ p_mono_poly) {
    const std::vector<int> &r_mono_poly = *p_mono_poly;

    gllinewidth(2);
    glcolor3f(0, 0, 1);
    glBegin(GL_liNE_LOOp);
    for(size_t i = 0, n = r_mono_poly.size(); i < n; ++ i)
        glVertex2f(my_polygon[r_mono_polY[i]].x, my_polygon[r_mono_polY[i]].y);
    glEnd();
    glPointSize(2);
    glBegin(GL_POINTS);
    for(size_t i = 0, n = r_mono_poly.size(); i < n; ++ i)
        glVertex2f(my_polygon[r_mono_polY[i]].x, my_polygon[r_mono_polY[i]].y);
    glEnd();
    // draw the sliced part of the polygon

    int n_top = 0;
    for(size_t i = 0, n = r_mono_poly.size(); i < n; ++ i) {
        if(my_polygon[r_mono_polY[i]].y < my_polygon[r_mono_polY[n_top]].y)
            n_top = i;
    }
    // find the top-most point

    gllinewidth(1);
    glcolor3f(0, 1, 0);
    glBegin(GL_liNE_Strip);
    glVertex2f(my_polygon[r_mono_polY[n_top]].x, my_polygon[r_mono_polY[n_top]].y);
    for(size_t i = 1, n = r_mono_poly.size(); i <= n; ++ i) {
        int n_which = (n_top + ((i & 1)? n - i / 2 : i / 2)) % n;
        glVertex2f(my_polygon[r_mono_polY[n_which]].x, my_polygon[r_mono_polY[n_which]].y);
    }
    glEnd();
    // draw as if triangle Strip
}

该代码不是最佳代码,但应该易于理解。在开始时,将创建一个凹面多边形。然后创建顶点的“工作集”。在该工作集上,将计算一个排列,该排列按顶点的y坐标对它们进行排序。然后,将该排列循环遍历,以寻找分裂点。一旦找到分割点,就会创建一个新的单调多边形。然后,将新多边形中使用的顶点从工作集中删除,然后重复整个过程。最后,工作集包含无法分割的最后一个多边形。最后,将渲染单调多边形以及三角带顺序。有点混乱,但是我敢肯定您会弄清楚的(这是C ++代码,只需将其放在gluT窗口中,然后看它能做什么)。

希望这可以帮助 …

解决方法

我正在寻找一种快速的 多边形三角剖分算法 ,该 算法 可以将不是很复杂的2D凹面多边形(无孔) 三角剖 分成 三角形,
准备发送给OpenGL ES进行绘制GL_TRIANGLE_StriP

我知道一些算法,但找不到适合我需求的算法:

  • http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
    • 该算法可以正常工作,但问题是它返回了无法使用的简单三角形GL_TRIANGLE_StriP,需要使用GL_TRIANGLES它,在大量顶点上效率不高。
  • http://code.google.com/p/iphone-glu/
    • 它没有任何示例关联,我找不到在OpenGL ES 2.0的iOS上成功使用过它的人
    • 我不知道它返回什么,而且好像也调用了我不想要的相应OpenGL命令-我只需要返回三角形
    • 它会泄漏内存

我正在开发的平台是:iOS,OpenGL ES 2.0,cocos2d 2.0。

谁能帮我一个这样的算法?或任何其他建议将不胜感激。

大佬总结

以上是大佬教程为你收集整理的OpenGL ES的多边形三角剖分成三角形带全部内容,希望文章能够帮你解决OpenGL ES的多边形三角剖分成三角形带所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: