Visulalization Voronoi in OpenSceneGraph

Visulalization Voronoi
in OpenSceneGraph

[email protected]

Abstract. In
mathematics a Voronoi diagram is a way of dividing space into a number of
regions. A set of points, called seeds, sites, or generators is specified
beforehand and for each seed there will be a correspoinding region consisting of
all points closer to that seed than to any other. The regions are called Voronoi
cells. It is dual to the Delaunay triangulation. It is named after Georgy
Voronoy, and is also called a Voronoi tessellation, a Voronoi decomposition, a
Voronoi partition, or a Dirichlet tessellation. Voronoi diagrams can be found in
a large number of fields in science and technology, even in art, and they have
found numerous practical and theoretical applications. The paper use
OpenSceneGraph to visualize the Voronoi diagram.

Key words. Voronoi,
C++, OpenSceneGraph, Visualization

1. Introduction

计算几何(Computational
Geometry)作为一门学科,起源于20世纪70年代,经过近四十多年的发展,其研究内容不断扩大,涉及Voronoi图、三角剖分、凸包、直线与多边形求交、可见性、路径规划、多边形剖分等内容。据相关统计,在数以千计的相关文章中,约有15%是关于Voronoi图及其对偶(dual)图Delaunay三角剖分(Delaunay
Triangulation)的研究。由于Voronoi图具有最近性、邻接性等众多性质和比较系统的理论体系,如今已经在计算机图形学、机械工程、地理信息系统、机器人、图像处理、大数据分析与处理、生物计算及无线传感网络等领域得到了广泛应用,同时也是解决碰撞检测、路径规划、可见性计算、骨架计算以及凸包计算等计算几何所涉及的其他问题的有效工具。

Voronoi图的起源最早可以追溯到17世纪。1644年,Descartes用类似Voronoi图的结构显示太阳系中物质的分布。数学家G.L.
Dirichlet和M.G.Voronoi分别于1850年和1908年在他们的论文中讨论了Voronoi图的概念,所以Voronoi图又叫Dirichlet
tessellation。在其他领域,这个概念也曾独立地出现,如生物学和生理学中称之为中轴变换(Medial Axis
Transform)或骨架(Skeleton)。化学与物理学中称之为Wigner-Seitz
Zones,气象学与地理学中称之为Thiessen多边形。Voronoi图最早由Thiessen应用于气象观测站中随机分布的研究。由于M.G.
Voronoi从更通用的n维情况对其进行研究和定义,所以Voronoi图这个名称为大多数人所使用。

在路径规划、机械加工、模式识别、虚拟现实、生物计算等领域,将站点从离散点扩展到线段圆弧等生成Voronoi图的方式也是非常常见的。

目前可用于生成Voronoi图的库有一些,很多是开源库。像CGAL库、boost中也提供了生成Voronoi图的算法。本文根据Shane O
Sullivans1封装的Voronoi库,并用OpenSceneGraph显示出剖分结果。

2.
Implementation

用Shane O
Sullivans封装的VoronoiDiagramGenerator可以生成点集的Voronoi图,得到剖分的线段。程序小巧,易于使用。结合OpenSceneGraph将剖分得到的线段显示出来。程序代码如下所示:


/*
* Copyright (c) 2014 eryar All Rights Reserved.
*
* File : Main.cpp
* Author : [email protected]
* Date : 2014-04-30 18:28
* Version : V1.0
*
* Description : VoronoiViewer for voronoi library visulization.
*
*/

#include "VoronoiDiagramGenerator.h"

// OpenSceneGraph library.
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgGA/StateSetManipulator>
#include <osgViewer/ViewerEventHandlers>

#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgViewerd.lib")

osg::Node* BuildVoronoi(void)
{
osg::ref_ptr<osg::Geode> theGeode = new osg::Geode();
osg::ref_ptr<osg::Geometry> theLines = new osg::Geometry();
osg::ref_ptr<osg::Vec3Array> theVertices = new osg::Vec3Array();

const long thePointCount = 10;
float *xValues = new float[thePointCount] ();
float *yValues = new float[thePointCount] ();

float theMin = 0.0;
float theMax = 100.0;

float x1 = 0.0;
float y1 = 0.0;
float x2 = 0.0;
float y2 = 0.0;

// Draw the boundary box.
theVertices->push_back(osg::Vec3(theMin, 0.0, theMin));
theVertices->push_back(osg::Vec3(theMin, 0.0, theMax));

theVertices->push_back(osg::Vec3(theMin, 0.0, theMin));
theVertices->push_back(osg::Vec3(theMax, 0.0, theMin));

theVertices->push_back(osg::Vec3(theMin, 0.0, theMax));
theVertices->push_back(osg::Vec3(theMax, 0.0, theMax));

theVertices->push_back(osg::Vec3(theMax, 0.0, theMin));
theVertices->push_back(osg::Vec3(theMax, 0.0, theMax));

// initialize random seed:
srand(time(NULL));

// Sites of the Voronoi.
for (int i = 0; i < thePointCount; ++i)
{
xValues[i] = rand() % 100;
yValues[i] = rand() % 100;

// Draw the site.
theVertices->push_back(osg::Vec3(xValues[i] - 1.0, 0.0, yValues[i]));
theVertices->push_back(osg::Vec3(xValues[i] + 1.0, 0.0, yValues[i]));

theVertices->push_back(osg::Vec3(xValues[i], 0.0, yValues[i] - 1.0));
theVertices->push_back(osg::Vec3(xValues[i], 0.0, yValues[i] + 1.0));
}

// Generate Voronoi Diagram.
VoronoiDiagramGenerator vdg;
vdg.generateVoronoi(xValues, yValues, thePointCount, theMin, theMax, theMin, theMax);
vdg.resetIterator();

while (vdg.getNext(x1, y1, x2, y2))
{
theVertices->push_back(osg::Vec3(x1, 0.0, y1));
theVertices->push_back(osg::Vec3(x2, 0.0, y2));
}

theLines->setVertexArray(theVertices);

// Set the colors.
osg::ref_ptr<osg::Vec4Array> theColors = new osg::Vec4Array();
theColors->push_back(osg::Vec4(1.0f, 1.0f, 0.0f, 1.0f));

theLines->setColorArray(theColors);
theLines->setColorBinding(osg::Geometry::BIND_OVERALL);

// Set the normal.
osg::ref_ptr<osg::Vec3Array> theNormals = new osg::Vec3Array();
theNormals->push_back(osg::Vec3(0.0f, -1.0f, 0.0f));

theLines->setNormalArray(theNormals);
theLines->setNormalBinding(osg::Geometry::BIND_OVERALL);

theLines->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, theVertices->size()));

theGeode->addDrawable(theLines);

// Free the meomry.
delete [] xValues;
delete [] yValues;

return theGeode.release();
}

int main(int argc, char* argv[])
{
osgViewer::Viewer myViewer;

myViewer.setSceneData(BuildVoronoi());

myViewer.addEventHandler(new osgGA::StateSetManipulator(myViewer.getCamera()->getOrCreateStateSet()));
myViewer.addEventHandler(new osgViewer::StatsHandler);
myViewer.addEventHandler(new osgViewer::WindowSizeHandler);

return myViewer.run();
}

上述程序生成结果如下所示:

Figure 2.1 Voronoi Diagram in OpenSceneGraph

修改站点的数量,生成的Voronoi图如下所示:

修改范围时也要修改生成范围中点的随机函数的取余操作,避免生成点超出范围。

Figure 2.2 Less Sites of the Voronoi Diagram

Figure 2.3 More Sites of the Voronoi Diagram

3. Conclusion

Shane O
Sullivans封装的库小巧,使用方便,速度还很快。也有些不足,如不能取得一个站点对应的多边形,即某个点属于哪个区域。不能得到带权点集的Voronoi剖分。

源程序小巧,借助程序代码来对Voronoi的概念进行理解还是不错的。

4. References

1. Shane O Sullivans, http://www.skynet.ie/~sos/mapviewer/voronoi.php

2. http://ect.bell-labs.com/who/sjf/

3. 汪嘉业, 王文平, 屠长河, 杨承磊. 计算几何及应用. 科学出版社. 2011

4. 杨承磊, 吕琳, 杨义军, 孟祥旭. Voronoi图及其应用. 清华大学出版社. 2013

PDF Version and Source code: Visualization Voronoi in OpenSceneGraph

Visulalization Voronoi in OpenSceneGraph,码迷,mamicode.com

时间: 2024-08-24 11:09:19

Visulalization Voronoi in OpenSceneGraph的相关文章

Visulalization Boost Voronoi in OpenSceneGraph

Visulalization Boost Voronoi in OpenSceneGraph [email protected] Abstract. One of the important features of the boost polygon library is the implementation of the generic sweepline algorithm to construct Voronoi diagrams of points and linear segments

访问调度控制 时间控件

Visulalization Voronoi in OpenSceneGraph [email protected] Abstract. In mathematics a Voronoi diagram is a way of dividing space into a number of regions. A set of points, called seeds, sites, or generators is specified beforehand and for each seed t

BOOST Voronoi Visualizer

BOOST Voronoi Visualizer [email protected] Abstract. The Voronoi extension of the Boost.Polygon library provides functionality to construct a Voronoi diagram of a set of points and linear segments in 2D space with some limitations. The paper mainly d

OpenSceneGraph in ActiveX by ActiveQt

OpenSceneGraph in ActiveX by ActiveQt [email protected] Abstract. Qt’s ActiveX and COM support allows Qt for Windows developers to access and use ActiveX controls and COM objects provided by any ActiveX server in their Qt applications. Make their Qt

OpenSceneGraph 笔记--如何导出三角形数据

OpenSceneGraph 笔记--如何导出三角形数据 转载:http://blog.csdn.net/pizi0475/article/details/5384389 在OpenSceneGraph开发中,为了方便会经常使用到一些不是三角形片的数据,比如四边形等数据.例如画一个管子用四边形带比用三角形片好计算得多.比如现在我们要画一个由两个平面组成的面,我可以这样做: osg::Geode* geode=new osg::Geode;    osg::Geometry* polyGeom =

OpenSceneGraph几个重要功能节点练习

OpenSceneGraph几个重要功能节点练习 一. 空间变换节点 空间变换中最重要的是坐标系和矩阵运算了.OSG坐标系中使用右手系,Z轴垂直向上,X轴水平向右,Y轴垂直屏幕向里,与OpenGL和DirectX都不同.相关缩放.旋转和平移主要由osg::Matrix, osg::Vec3, osg::Quat几个类来完成.局部坐标系向世界坐标系转换规则是:设在局部坐标系下顶点 V 转换成世界坐标系坐标 V': V' = V * Mn* Mn-1*……* M3* M2* M1* M0 其中M0到

OpenSceneGraph是一个开源的三维引擎

http://www.osgchina.org/OpenSceneGraph是一个开源的三维引擎,被广泛的应用在可视化仿真.游戏.虚拟现实.科学计算.三维重建.地理信息.太空探索.石油矿产等领域.OSG采用标准C++和OpenGL编写而成,可运行在所有的Windows平台.OSX.GNU/Linux.IRIX.Solaris.HP-Ux.AIX.Android和FreeBSD 操作系统.OSG在各个行业均有着丰富的扩展,能够与使用OpenGL书写的引擎无缝的结合,使用国际上最先进的图形渲染技术,

Jump Flood Algorithms for Centroid Voronoi Tessellation

Brief Implemented both CPU and GPU version, you could consider this as the basic playground to implement the more advanced feature such as support arbitrary shape in 2D space, or by radix-sort to restore the analytic shape of each Voronoi region etc.

OpenCV生成点集的Delaunay剖分和Voronoi图

实现内容: 设置一副图像大小为600*600,图像像素值全为0,为黑色. 在图像中Rect(100,100,400,400)的区域随机产生20个点,并画出. 产生这些点集的Delaunay剖分和Voronoi图,并画出. 程序 #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> using namespace cv; using