Ly Phan

Home | Projects | Education | Misc.


CSE546T - Computational Geometry

Final Project

Goal: Partition a 3D mesh into equal regions using LLoyd's algorithm on Voronoi diagram.

Preprocessing: Randomly place centroids on mesh: O(n)

Step 1: Build Voronoi diagram:

Grow regions out from each centroid until it meets with another region.

Each vertex is entered into a priority queue keyed on its distances to the nearest centroid. This distance is calculated using Djikstra's algorithm on graph. The vertex with shortest distance to a centroid is assigned to the region with that centroid. Edge length can be set to either the actual edge length or 1 (which is equivalent to building Voronoi regions using edge number).

Runtime: Each vertex is added to and removed from queue only once: O(n)

Refine Voronoi diagram: If a region is cylinder-like, insert a new centroid nearby to break it into two new disk-like regions. Runtime: O(n)

Step 2: Relax Voronoi regions: Two approaches:

Approach 1: For each region, calculate the average point of all vertices in 3D and assign the closest vertex to be the new centroid. Runtime: O(n)

Approach 2: For each region, map it to a plane using Desbrun's natural parameterization. Then calculate the average point of all vertices in 2D and find the closest vertex a in 2D. Finally assign the correspondent vertex b in 3D to be the new centroid. Runtime: O(n^3)

Pseudocode with time complexity analysis

SeedCentroids() - O(n)
   Randomly place k centroids on mesh

GrowRegions() - O(n^2)
   While PQ (primary queue) is not empty
      For each region
         For each neighbor of each vertex on the boundary of the current region
            If it is not assigned to a region
                Calculate minimum distance to the region's centroid
                If vertex is not in queue, enter into queue
                Else compare and update vertex's key in PQ if necessary
            EndIf
         EndFor
      EndFor
      Remove the first vertex from PQ and assign to associated region
   EndWhile
Each vertex is entered and remove from queue once, but might be updated upto n times

SplitRegions() - O(n^2)
   For each region
      Trace around the boundary until completing a loop
      If there are unvisited vertices on the boundary
         Divide boundary vertices into two groups
         Calculate maximum shortest distance to each group and correspondent vertex
         Add a new centroid at the midpoint between these two vertices
      EndIf
   EndFor
Each vertex is visited at most a constant number of times

Relax1() - O(n)
   Calculate the average point of all vertices within each region in 3D
   Find a vertex in this region that is closest to the average point
   Assign it as the new centroid
Each vertex is visited at most a constant number of times

Relax2() - O(n^3)
   Parameterize each region onto the plane using Desbrun's Natural Parameterization
      This involves solving a linear system using LAPACK library, hence O(n^3)
   Calculate the average point of all vertices within the region in 2D
   Find a vertex in this 2D region that is closest to the average point
   Assign the correspondent 3D vertex to be the new centroid

Total runtime O(n^3)


Implementation details

The project is written in C, the main class is implemented in ~1500 lines of code

Design issues:
   How to find new centroid for each 3D region accurately
   Growing regions on anisotropic mesh (varied edge length)

Challenge:
   Debugging special cases is always a challenge

Data structure from Cindy's code database:
   PMeshLite to store and perform calculations on mesh

Visualization routines from Cindy's code database:
   MeshViewer


Initial results and conclusions

    Growing regions using Geodesic distance with actual edge length gives better result
    Relaxing using average points in 3D without parameterizing the regions yields better runtime and improves the partitions faster, but relaxing with parameterization step converges better, especially when regions are larger with higher curvature.


Initial regions

     
Approach 1                                                           Approach 2
After 6 iterations

More images

[Back to top]