|
OverviewThe goal of this project is to explore a Voronoi tesselation technique for vector fields. In particular, I would like to implement the Centroidal Voronoi tesselation (CVT) technique discussed in the paper shown below in the references section. This algorithm takes a vector field and an input value k and tesselates a vector field into k Voronoi cells such that the overall energy (in terms of a chosen distance metrics) is equalized in each cell. The centroid of each cell is then used as the representation for the entire cell; as they represent some mean value for all the values in that cell.I would like to extend the techniques discussed in this paper by instead of using a hedgehog representation using an advection based technique. In particular I would like to use streamlets to represent each cells. I believe that this will create a compact representation in that the tesselation simplifies the field, but will be more visually informative than a simple "mean hedgehog" for each cell. One other direction to go is to create a seed set within each region that best approximates it, instead of just using one seed per cell. I would like to do some of this work using the visualization tool Amira, but at the moment (as discussed with Dr. Crawfis), obtaining a development version of this tool will be difficult. The plan I will most likely end up using is to do the coding in OpenGL. I will first use analytic vector fields where I will be able to have better knowledge as to what the resulting field will look like. I may also try some different vector field datasets as well. I'm not completely sure, but one thing I may be able to do is experiment with different metrics as well instead of the one used in the "traditional" CVT. Timeline
Results (Diary)Mon, 5.23.05. I've settled on doing the CVT paper instead of the vector field topology one (this was up in the air as of this morning). I've emailed the folks at Amira to see about obtaining a dev copy, but I'm leaning towards just doing it in OpenGL.Also, I've completely some code that does a simple CVT of a 2d pointset. Here it just uses Euclidean distance for the metric. It's nothing special, but the code and VS6 project are available here. Thu, 5.26.05. Amira is out; couldn't get a hold of a Dev version. As for progress, I'm about right on schedule. I have modified the tool from the last entry to do CVTs for analytic 2d vector fields. Below is a screenshot. ![]() This image was generated with this source. It's of the vector field (-y/(x^2 + y^2), x/(x^2 + y^2)) which is a simple spiral sink. There are 50 cells created over a random sampling (taken using rand()) of 5000 points over the field defined on domain [-1,1]x[-1,1]. The above image shows the convex hull of each cell in the CVT as well as the centroid with a hedgehog. It's quite ugly but it's the basics for what I'd like to do. You can see the larger cells are areas of lower curvature while areas of rapid change have small cells. There is a similar inverse correlation between cell size and magnitude of the vector field. The CVT groups points that have a nearness of vector magniture, curve, and position, so in areas of high curvature, the vector field is changing rapidly and hence needs small cells to capture the similar regions. Rapid changes in the magnitude of the vector field should be captured as well. One important note here is the distance function used. I used the one from the paper, it's a one-sided distance between a point, p, and a centroid, m. If at a point a, v_a is the vector field at that point and x_a is the position the distance d(p,m) is defined: d(p,m) = |v_p| * sqrt(1 - cos(theta) + |x_p - x_m|^2) where theta is the angle between v_p and v_m. It should be noted that each centroid, m, is calculated (and maintained) to have v_m be a unit vector. The 45 underneath means that I ran the CVT for 45 iterations (until it was minimal). This took a couple of minutes with 5000 points which is unfortunate. I do also have to calculate 50 convex hulls which slowed it down some, but the main portion of the calculation is figuring out the k-mean cells and moving the points around. I also tried out some other simple planar vector fields (a source, center, and saddle), but I do not have images of them. In addition, I had done a uniform sampling of the vector field, which worked fine. However, my convex hull algorithm, hastily thrown together, did not like taking the hulls where so many points were collinear, so it would tend to crap out. Hence no pretty pictures. Next I'll implement some advection to create streamlets and I'll also do 3d. Fri, 5.27.05. I'm a bit behind in that I didn't implement 3d or advection yet, but this afternoon I was busy with other things. I did however put in a more complicated example, shown below: ![]() The above shows three images of the field: dx/dt = -(y-0.5)(y+0.5)/sqrt(x^2 + y^2) dy/dt = (x-0.5)(x+0.5)/sqrt(x^2 + y^2) Which has four critical points, 2 saddles, and 2 spiral sources (bottom left and top right). You can't actually tell if they are sinks, sources, or centers very easily with the hedgehogs. Partially this could be solved using more cells, but I believe advection will better handle it. The cells centroids tend to move away from the actual critical point, so it's somehow a bit harder to see regions of interest clearly. Some stats on this image. 50 cells, 5000 random sample points in the vector field on domain [-1,1]x[-1,1]. It took 68 iterations of the algorithm to finish here. Also the image has been resized by half. Below I show the same vector field with 200 cells which was built in 15 iterations. It's clearer, definitely. Also, one thing I've noticed is that this gives a nice, non-uniform sampling of the vector field. So some of the artifacts from uniform sampling are now removed: ![]() Sun, 5.29.05. I've modified the 2d code to draw streamlets using a 4th order Runge-Kutta approximation. The source code that does this is here. I've made some animations of a few different vector fields that I've experimented with. For each, I show the construction of the tesselation at each iteration of the algorithm. There's a big jump at the first step when it places the means in nice places (since initially they are random), but after that there's a nice smooth progress. I will talk about each experiment in turn.
Thurs, 6.02.05. I've done some work this evening to do some simple experiments in 3d. Unfortunately my code lacks some of the bells and whistles like lighting and shading, which really would lend, but you can get a pick of the applicability here to higher dimension. The source code used in these experiments is available here. Again I've made some animations of the construction of the CVT for some choice vector fields. By now it's clear that animating isn't the best way really to view the results. It's fairly obvious that without only a couple of iterations the goals of the construction have been achieved---an even set of points within the vector field such that they're balanced by the CVT. However, I still the did the animations since I had the code to snapshot the pictures and it wasn't a lot of effort. I didn't do the hedgehog plots here for two reasons. 1.) the hedgehogs and hulls would be hard to see. 2.) My convex hull code is buggy, extending it to 3d would have required major effort, and as we saw in Experiment 3, the convex hulls aren't the best representation since they can overlap. I do, however, have animations of a couple of different views for each field. I've drawn the bound box [-1,1]x[-1,1]x[-1,1] in each animation, and the axes are shown in x-Red, y-Green, z-Blue.
ConclusionsCentroidal Voronoi Tesselation boils down to a fancy way to do k-means of a vector field sample. It's handy in that it provides a nice measure of distance between two vectors in the field, and by doing so can create a partition of the space. From this partition, one can select a representative vector (i.e. the centroid) and use that to simplify visualization.Some nice trends. First the applicability to higher dimensions. The Voronoi cells will always be a balanced partition. Second, one can see clearly in many of the examples above that the CVT captures regions of higher change by using smaller cells. This is desirable in that there will be more smaller cells (and consequently more representatives) in areas of high change, which are often of interest or necessitate the additional information. Some less nice trends. The Voronoi cells, as a result of the projection from a 4d space to 2d space have no guarantee to be convex. This can create confusion. Also, the k-means operation is expensive (although it could be considered a pre-processing step), it's use might not always be justified. On the examples above, they would run normally in only a minute or two, but with a larger sample the time spent might not be justifiable by the results Ultimately though, the CVT doesn't really solve some of the crucial problems to visualization. As shown by these experiments, using an icon like a hedgehog really limits the understanding of the data, and in higher dimensions is basically useless. Streamlets do create better representations, but are still limited. This algorithm provides a method to create a balanced simplification, but representing even that simplified data in the best way is still open-ended. ReferencesQiang Du and Xiaoqiang Wang. Centroidal Voronoi tessellation based algorithms for vector fields visualization and segmentation. IEEE Visualization, 2004. |