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

会看到如下的效果:

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

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

osg 示例程序解析之osgdelaunay的更多相关文章

  1. ACEXML解析XML文件——简单示例程序

    掌握了ACMXML库解析XML文件的方法后,下面来实现一个比较完整的程序. 定义基本结构 xml文件格式如下 <?xml version="1.0"?> <roo ...

  2. OSG中的示例程序简介

    OSG中的示例程序简介 转自:http://www.cnblogs.com/indif/archive/2011/05/13/2045136.html 1.example_osganimate一)演示 ...

  3. OSG中的示例程序简介(转)

    OSG中的示例程序简介 1.example_osganimate一)演示了路径动画的使用 (AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera ...

  4. <WebGIS之OpenLayers全面解析>示例程序运行问题

    运行<WebGIS之OpenLayers全面解析>中的示例程序时,无法加载*.json文件. 查看到提示如下错误:GET http://localhost:11232/demos/data ...

  5. 【ABAP系列】SAP ABAP解析XML的示例程序

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[ABAP系列]SAP ABAP解析XML的示例 ...

  6. 【rabbitmq】rabbitmq概念解析--消息确认--示例程序

    概述 本示例程序全部来自rabbitmq官方示例程序,rabbitmq-demo: 官方共有6个demo,针对不同的语言(如 C#,Java,Spring-AMQP等),都有不同的示例程序: 本示例程 ...

  7. [OSG]OSG例子程序简介

    1.example_osganimate一)演示了路径动画的使用(AnimationPath.AnimationPathCallback),路径动画回调可以作用在Camera.CameraView.M ...

  8. RocketMQ生产者示例程序

    转载请注明出处:http://www.cnblogs.com/xiaodf/ 本示例展示了一个RocketMQ producer的简单实现,通过解析文本文件获取输入数据,将数据经过Avro序列化后发送 ...

  9. epub、ocf等常用电子书格式浅析----附JAVA示例程序

    一. 电子书介绍 转载请注明http://www.cnblogs.com/xckk/p/6020324.html Epub(Electronic Publication)是一个完全开放和免费的电子书标 ...

随机推荐

  1. 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ ProcessBar)

    一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得前两篇文章吗.主要讲述了以“jQuery的方式如何开发插件”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方式各有利 ...

  2. 回车符(CR)与换行符(LF), '\r'和'\n'的区别

    回车”(Carriage Return)和“换行”(Line Feed)这两个概念的来历和区别.在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33,Linux/Unix下 ...

  3. 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项

    我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...

  4. Android 学习笔记

    1.sleep(),wait(),notify(),notifyAll() sleep()是线程类的静态方法,阻塞线程一定时间后再次使线程处于可以被调度运行的状态wait(),notify(),not ...

  5. Python入门(一)

    Python版本:Python 2.7.5 Python是一种面向对象.解释型计算机程序设计语言 1.基本操作符python的除法的结果会随着数值类型的变化而变化整数相除,结果会取整实数相除,结果会取 ...

  6. js跨域解决方案(转载)

    1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题. 跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本 ...

  7. 自定义el函数

    1.1.1 自定义EL函数(EL调用Java的函数) 第一步:创建一个Java类.方法必须是静态方法. public static String sayHello(String name){ retu ...

  8. android so调试时遇到的坑 - arm流水线

    直接看下面这段ARM汇编: 此时运行到的代码为ADD R3,PC 此时看一下寄存器窗口的值: 按理来说执行完ADD R3,PC后的效果应该是R3=R3+PC ,R3=40A1D5C8 但是我们可以执行 ...

  9. js中选定元素slice()

    选定元素slice() slice() 方法可从已有的数组中返回选定的元素. 语法 arrayObject.slice(start,end) 参数说明: 1.返回一个新的数组,包含从 start 到 ...

  10. .NET LINQ查询操作中的类型关系

    LINQ 查询操作中的类型关系      若要有效编写查询,您应该了解完整的查询操作中的变量类型是如何全部彼此关联的. 如果您了解这些关系,就能够更容易地理解文档中的 LINQ 示例和代码示例. 另外 ...