zoukankan      html  css  js  c++  java
  • osg 示例程序解析之osgdelaunay

    osg 示例程序解析之osgdelaunay

    转自:http://lzchenheng.blog.163.com/blog/static/838335362010821103038928/

    本示例程序主要说明如何用osgUtil::DelaunayTriangulator类建立约束的delaunay(德洛内)三角网,delaunay(德洛内)三角网主要用于基于离散点数据构建三维表面。如经常用于构建地形表面,本示例程序就是用该类构建一个地形,然后添加一些约束条件,在地形上绘制道路、区域等要素,示例程序的主要函数为:makedelaunay(),该函数输入的参数是约束的数目,输出的是一个组节点,下面对这个函数的实现进行说明。

    1、生成离散点数据

    该函数首先随机生成一些离散点数据,代码如下:

    //随机生成地形坐标点,存储到Points中
     int eod=0;
     while(eod>=0) {
         osg::Vec3d pos=getpt(eod);
         if (pos.z()>-10000){
               points->push_back(pos);
               eod++;
          }

          else {
             eod=-9999;
           }
     }

    2、生成一些约束类,这些类派生与osgUtil::DelaunayConstraint,如
     osg::ref_ptr<ArealConstraint> dc2; 约束区域
     osg::ref_ptr<ArealConstraint> forest; 约束区域,作为一片树林
     osg::ref_ptr<LinearConstraint> dc3;  约束区域,一条线
     等等,然后确定约束的边或点,如当输入的参数大于0时,确定金字塔的底边作为约束边,如下代码所示:

    //令5个金字塔的底边作为约束边
      for(unsigned int ipy=0; ipy<5; ipy++){
           osg::ref_ptr<pyramid>pyr=new pyramid;
           float x=2210+ipy*120, y=1120+ipy*220;
           //设置金字塔绘制的位置及大小尺寸
           pyr->setpos(osg::Vec3(x,y,getheight(x,y)),125.0+10*ipy);
           //确定金字塔底面4边形4个顶点坐标
           pyr->calcVertices(); //make vertices
           //底面4条边构成约束

            pyr->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP,0,4) );
           //添加约束边,金字塔底面4边形4条边作为约束
           trig->addInputConstraint(pyr.get());
           //存储约束边
           pyrlist.push_back(pyr.get());
      }

      addInputConstraint()方法用于向三角网中添加约束条件。

    其余的约束条件的生成与添加与其类似。

    3、三角化处理

    添加完约束条件后,进行三角化处理,如下代码所示:

    trig->setInputPointArray(points);
     osg::Vec3Array *norms=new osg::Vec3Array;
     trig->setOutputNormalArray(norms);
     //三角化处理
     trig->triangulate();

    4、将三角化的图元添加到叶节点中

    //添加构建的三角形作为图元
    gm->addPrimitiveSet(trig->getTriangles());
    gm->setNormalArray(trig->getOutputNormalArray());
    gm->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
    geode->addDrawable(gm.get());

    5、绘制约束的几何体

    为了方便看出约束的效果,我们用线框的方式显示图形,把叶节点的状态改为线框显示方式。

    osg::PolygonMode *pLolyMode=new osg::PolygonMode();
     pLolyMode->setMode(osg::PolygonMode::FRONT_AND_BACK ,osg::PolygonMode::LINE);
     stateset->setAttribute(pLolyMode);
     geode->setStateSet( stateset );

    在绘制约束体之前,先要使用removeInternalTriangles()方法,移开约束条件构建的三角形,对于绘制金字塔的代码:

    for ( std::vector < pyramid* >::iterator itr=pyrlist.begin(); itr!=pyrlist.end(); itr++) {
           //移开金字塔约束边形成的三角形,形成4个4边形空洞
           //trig->removeInternalTriangles(*itr);
          //绘制金字塔 

           //geode->addDrawable((*itr)->makeGeometry()); // this fills the holes of each pyramid with geometry
      }

     如果我们注释以下两句:

     //trig->removeInternalTriangles(*itr);
    //geode->addDrawable((*itr)->makeGeometry()); // this fills the holes of each pyramid with geometry

    会看到如下的效果:

    osg 示例程序解析之osgdelaunay - 陈恒 - 陈恒的博客

     我们看到受约束的地方仍然形成了三角形,没有生成生4边形的空洞,如果我们把第一句的注释去掉,会看到如下结果:

    osg 示例程序解析之osgdelaunay - 陈恒 - 陈恒的博客

     说明建立约束条件后,只有使用trig->removeInternalTriangles()方法,才能使约束生效,通过本示例程序,我们可以知道如何基于离散点及约束条件,构建受约束的三角网的方法

  • 相关阅读:
    async await promise 执行时序
    理解prototype
    X-Requested-With
    event事件传播规则
    【小文】Flask web Hello程序!
    【小文】php-gtk: Hello!
    【小文】HTTP 状态码
    【小文】Python环境安装配置
    C语言:趣味小问题 鸡兔同笼
    C语言:趣味小问题 百钱买百鸡
  • 原文地址:https://www.cnblogs.com/flylong0204/p/4616195.html
Copyright © 2011-2022 走看看