tclsensorstriangulationns2delaunay

Implementing Boyer Watson algorithm for Delaunay Triangulation in Network Simulator ns2


I want to implement Delaunay Triangulation in Network Simulator ns2. Till now I know how to add nodes, how to make them move, How to set a traffic, and the basic things. Sample tcl scripts runs perfectly in nam(network animator). I am confused that, to implement Boyer Watson algorithm for Delaunay triangulation, the first step is to draw a super triangle which includes all the nodes. I am using wireless nodes and able to get the coordinates of the randomly distributed nodes. Also I could manage to get the Euclidean distance between each node to all others. When I searched for drawing in ns2, it all says about xgraph. But I wish if I could implement it inside nam. So where to start to draw a super triangle for my wireless sensor network? Is there something wrong what I am thinking about? Posting Boyer Watson Algorithm below. Please anyone help?

// pointList is a set of coordinates defining the points to be triangulated
triangulation := empty triangle mesh data structure
add super-triangle to triangulation // must be large enough to completely contain all the points in pointList
for each point in pointList do // add all the points one at a time to the triangulation
  badTriangles := empty set
  for each triangle in triangulation do // first find all the triangles that are no longer valid due to the insertion
     if point is inside circumcircle of triangle
        add triangle to badTriangles
  polygon := empty set
  for each triangle in badTriangles do // find the boundary of the polygonal hole
     for each edge in triangle do
        if edge is not shared by any other triangles in badTriangles
           add edge to polygon
  for each triangle in badTriangles do // remove them from the data structure
     remove triangle from triangulation
  for each edge in polygon do // re-triangulate the polygonal hole
     newTri := form a triangle from edge to point
     add newTri to triangulation
for each triangle in triangulation // done inserting points, now clean up
  if triangle contains a vertex from original super-triangle
     remove triangle from triangulation
return triangulation



Solution

  • The easiest approach with something like this is to take the algorithm you have and transcribe it assuming that tricky bits are implemented by some command. Then pick one of the commands that is missing and work on implementing that. Repeat until you're done.

    proc computeTriangulation {pointList} {
        # must be large enough to completely contain all the points in pointList
        set superTriangle [computeSuperTriangle $pointList]
        set triangulation [list $superTriangle]
        foreach point $pointList {
            # add all the points one at a time to the triangulation
            set badTriangles {}
            set goodTriangles {}; # INTRODUCED VARIABLE! This is convenient time to split the data
            foreach triangle $triangulation {
                # first find all the triangles that are no longer valid due to the insertion
                if {[pointInCircumcircle $point $triangle]} {
                    lappend badTriangles $triangle
                } else {
                    lappend goodTriangles $triangle
                }
            }
            set polygon {}
            foreach triangle $badTriangles {
                # find the boundary of the polygonal hole
                foreachEdge edge $triangle {
                    if {[edgeIsUnshared $edge $badTriangles] && $edge ni $polygon} {
                        lappend polygon $edge
                    }
                }
            }
            set triangulation $goodTriangles; # effectively removes bad triangles from the data structure
            foreach edge $polygon {
                # re-triangulate the polygonal hole
                lappend triangulation [formTriangle $edge $point]
            }
        }
        # This is a standard pattern for doing list filtering where the filter is computed
        return [lmap triangle $triangulation {
            # done inserting points, now clean up
            if {[hasVertexFrom $triangle $superTriangle]} {
                continue
            }
            string cat $triangle
        }]
    }
    

    Now, all that's missing is computeSuperTriangle, pointInCircumcircle, foreachEdge, edgeIsUnshared, formTriangle and hasVertexFrom. But these are all easier to write than the overall algorithm. (You will need to decide how to represent a triangle; a list of vertex points might be good enough. And care must be taken in foreachEdge to always return edges in a form that is “consistent” or you'll get non-unique elements in polygon; I suggest something like sorting the points in the edge so that the minimum coordinates come first. After all, the order of points in an edge is arbitrary in this algorithm.)