opengl 学习小结 (二)——简单三角剖分

来源:互联网 发布:知乎 恐惧 编辑:程序博客网 时间:2024/06/05 15:34

  前一阵子一直在忙qt3d的一个项目,主要是被三角剖分的部分给难住。需要从一张图片中提取封闭轮廓,然后在qt3d中将这些轮廓立体呈现出来。qt3d中只提供了三角形和四边形的绘制接口,所以想要将任意一个封闭多边形画出来,必须要进行平面多边形的三角剖分(所谓三角剖分就是将一个多边形或一个曲面,用互不重叠的三角形拼凑出来,类似于微积分中的用小的线段逼近一条曲线一样,这里用许多的小三角形逼近一个曲面)。我处理的多边形是最简单的一类,不含孔洞不自相交的多边形。


一、基础知识

如何判断两条线段不相交:有两条线段ab和cd,令u = (a-c)x(d-c),v = (b-c)x(d-c);p = (c-a)x(b-a),q = (d-a)x(b-a)。若u·v≤0且p·q≤0,ab与cd相交,否则不相交。

如何判断一个点是否在一个三角形内部:设三角形abc,顶点p,分别构造向量ab,ac,ap,pb,pc,三角形的面积可以通过两条边向量的叉积表示,S△abc = 0.5*abs(abxac);分别计算S△abc,S△abp,S△acp,S△pbc,若 |S△abc - (S△abp + S△acp + S△pbc)|<0.005那么说明p点在△abc的内部或者边缘上。

如何判断一个多边形 的顶点是凹点还是凸点:这个需要结合顶点序列的方向来判断,结合前一个顶点和后一个顶点的相对位置来判断当前顶点是一个凸点还是一个凹点。

核心就是用到了向量的叉积:叉积的结果有正负,可以通过一个向量叉积两个不同向量来判断三个向量的位置关系,二维向量叉积大小是,以这两个向量为边的平行四边形面积。

 a×b=(a.y*b.z-a.z*b.y)i+(a.z*b.x-a.x*b.z)j+(a.x*b.y-a.y*b.x)k

二、算法流程

 1)将顶点序列,构造成一个双向循环顶点链表(从opencv函数返回的顶点序列是,逆时针的)。

typedef struct vert_node //顶点链表的节点
{
    int index;
    float x;
    float y;
    vert_node* next;
    vert_node* pre;
} my_vert,*pmy_vert;
2)判断当前链表中是否有大于2个结点,若不是跳转至6,否则再判断当前指针指向的顶点是否为凸点,若是一个凸点转到3,否则转到4。
3)以指针指向的当前顶点,当前顶点的前一顶点,及后一顶点,这三点构成的三角形中,是否包含链表中其余的任一顶点(用判断点是否在三角形边缘及内部的方法)。
若包含则转到4,否则转到5。
4)指针指向下一顶点,并转到2。
5)将当前顶点、前一顶点和后一顶点构成的三角形存储,从链表中删去当前结点,指针指向下一顶点,转到2。
6)删除当前结点和下一结点,算法结束。
      这个算法就是每次从多边形中,划去一个凸的三角形角,简单实用,速度也快。最开始我就是用的这个方法,但是没有加判断是否有其它顶点包含在当前要划去的三角形内,结果导致陷入死循环。后来采用一篇文章中递归剖分的方法,算法比较复杂,还要检测每次新添的一条边是否与原多边形相交,程序经常出问题,调试了一周也没调出来,最后又回到开始的思路,一下就出来了。下面贴几个效果图:

 

0 0
原创粉丝点击