How can I get a dictionary of cells from this Voronoi Diagram data?

后端 未结 5 1185
[愿得一人]
[愿得一人] 2021-02-07 13:17

Using the voronoi/delaunay diagram generation library found in this program, which is based on Fortune\'s original implementation of his algorithm, with a random set of points a

5条回答
  •  醉话见心
    2021-02-07 13:34

    Your list of edges is somehow incomplete, you need to add the ones at the border of the containing rectangle provided to the library call (seems to be 642,482 here). Technically, a Voronoi subdivision should use some infinite edges, but those are all finite. I assume that you also want these "open" polygons near this border, since they are all like that in your example.

    Adding those border edges seem not hard, just tedious. Probably something like, for each side of the main rectangle, find all vertices on it (ignoring corners), sort them (by x for the horizontal one, by y for vertical) and split that side using these values. This generates the missing edges, but don't add them directly to your main list, because they are special since they are the only ones not separating two cells.

    So, for the question itself, I would go like this: In your main list of edges (provided by the library), each edge separates two cells and if we find which ones, then we can just assign that edge to each one of these cells. Since a cell is equivalent to an input point, we will have the dictionary wanted, except with a list of edges instead of vertices, but that's easy to convert.

    Now to get these 2 cells: Calculate the middle point of the edge and from this, find the two nearest input points by simply iterating through the list while keeping the 2 smallest distances. By the properties of the Voronoi structure, those two are the ones forming the two cells. Note that these two distances should be equal, but the float imprecision will probably introduce a slight difference.

    To finish, add the border edges that we generated along the main rectangle, but for those, just use the first nearest input point, since they are only adjacent to one cell.

    Finally, we can convert each list of edges to a list of vertices (dump each ends points into a set). If you want to sort them in clockwise order, note that it's a convex polygon with an input point inside. So, you can just generate the vector going from the input point to each vertex, calculate its angle from one axis (use std::atan2(x,y)) and use this angle as comparator value to sort them (see std::sort).

提交回复
热议问题