Produce a random Voronoi diagram with a specific length and width? - algorithm

A Voronoi diagram is an approach to the tessellation of medium.
In this diagram, there are many points in a plane that divide the medium to many specific regions by their bisector. Any region is convex and has a circumscribed rectangle.
The circumscribed rectangle of convex shape that has the smallest area (We have an algorithm to imagine any edge on the direction of a specific edge and perpendicular to edge and find a rectangle with the smallest area.).
I want to place the points in a way that creat random convex polygons (Random means have different numbers of edges.).
But I want to control the size of the width and length of their circumscribed rectangle.
So I want to know is there any algorithm for the locating points with the above property?

Although I could not entirely follow your question note that Voronoi polygons have a strong combinatorial structure, so you should be careful what kind of "randomness" you expect for the number of Voronoi polygon edges.
Some more details: Since the Voronoi diagram is a planar graph with V Voronoi nodes, E Voronoi edges and F Voronoi polygons, you have
V - E + F = 2
due to Euler's formula. (Though, there is some technical detail with a vertex at infinity where all infinitely long Voronoi edges and unbounded Voronoi polygons meet.) Next, unless four of more input points would happen to lie on a circle, we have typically three Voronoi edges meeting at a Voronoi node, and therefore
3V = 2E
which gives
E = 3F - 6.
(Again, there is this technical detail with infinite Voronoi edges/polygons. If you have more than three infinite Voroni edges/polygons, say E', then you would have correct it to E = 3F - 3 - E'.)
Without going into too much detail, a "typical" Voronoi polygon actually has 6 edges. (Its dual graph is the Delaunay triangulation, so the dual assertion is that a vertex in the Delaunay triangulation has typically 6 triangulation edges incident.)
If you want to be more "flexible" on the number of edges then more than three Voronoi edges need to meet on a Voronoi node and therefore more than three input points need to be corcircular. Note that these circles are centered at the Voronoi nodes and in this sense you can even compute the number of such circles you need given the number F of Voronoi polygons and number E of Voronoi edges by Eulers formula:
V = 2 + E - F.
I hope this helped in getting a feeling on how Voronoi diagrams behave.

Related

Find exterior edge of triangles

A 3D surface is made from triangles with common vertices. I want to find the exterior edge, which might be concave.
All interior triangles have common vertices with neighbours. Ie no vertex is partway along an edge.
There are no holes. The surface is not closed.
From other posts here it seems the best way is to build a list of edges, then discard all edges that are duplicated. What should remain are the exterior lines.
This post mentions sorting the vertices in Min, Mid, Max order:
// Determine the ordering of vertices.
min_vertex = min(t.v1, t.v2, t.v3);
mid_vertex = median(p.v1, t.v2, t.v3);
max_vertex = max(t.v1, t.v2, t.v3);
Presumably, median(p.v1 should be t.v1, and v1 format is x-value, y-value, z-value of each vertex.
I cannot figure out how to do this after many hours, and would appreciate any plain-language help or algorithm.
Speed of calculation is not a huge factor. 5-10000 triangles in Excel/vba

Voronoi site points from Delaunay triangulation

How can one determine the exact Voronoi sites (cells/regions) from a Delaunay triangulation?
If one has an already constructed delaunay triangulation it is easy to calculate the edges of a voronoi by simply connecting adjacent circum-circle centers of every triangle.
It is also easy to determine the Voronoi points/sites because they are represented by every point of every triangle in the Delaunay triangulation.
However how do you determine that a specific voronoi site goes with a specific list of edges from a delaunay triangulation?
It seems it is simple to get one and the other as separate entities but putting them together is another challenge?
Looking at the diagram below, you can see the Delaunay triangulation along with the dual Voronoi diagram. All that I described can be pictured below for an easy reference. Ignore the green circle as that is just an artifact of this particular reference i took from the web.
If you want polygons from edges pick the midpoint of each edge and the distance to each site then sort the result and pick the first and second (when they are equal) and save them into polygons. For the borders there is of course only 1 edge. Maybe a dupe:Getting polygons from voronoi edges.
It's a bit tricky and hard to visualize. I am little stuck with the borders. Here is the original answer from Alink:How can I get a dictionary of cells from this Voronoi Diagram data?.
Each vertex in the Delaunay triangulation represents a Voronoi site. So to create the cell of a site you take one such triangle t and a vertex v in t. Now compute the Voronoi edges between v and the two remaining vertices of t. Repeat this process by traversing the triangles around v one by one. Assuming you can store the neighbourhood relation between the triangles this should at most take O(k) time, k being the number of adjacent triangles of v.
This converts the Delaunay triangulation into the Voronoi Diagram in O(n) time/space, for n sites. No sorting is required, otherwise what is the point in having the Delaunay triangulation in the first place.

Confusion on Delaunay Triangulation and Largest inscribed circle

I need to find a largest inscribed circle of a convex polygon, I've searched many sites and I get that this can be done by using Delaunay triangulation. I found a thread in CGAL discussion with an algorithm using CGAL:
You can compute this easily with CGAL:
First, compute the Delaunay triangulation of the points.
Then, iterate on all the finite faces of the triangulation.
For each finite face f
compute its circumcenter c
locate c in the triangulation (to speed up things, you can give one
vertex of f as starting hint for the point location)
if the face returned by locate(c,hint) is finite, then the circumcenter
c lies in the convex hull of the points, so, f is a candidate
if f is such a candidate face, compute its squared circumradius
keep only the face with minimum squared circumradius
The CGAL manual (chapter 2D triangulation, together with a few things
from the kernel) shows every basic function to do this.
I was a bit confused with the last part of this algorithm. When I read it what I understand from it is that the minimum circumradius of the triangulation face is the radius for the largest inscibed circle. But from examples of polygon with Delaunay triangulation, it seems that even the smallest circumcircle sometimes cannot fit inside the polygon, so how can this has the same radius as the largest inscribed circle?
Maximum inscribed circle in polygons.
The classical computational-geometry solution to the maximum inscribed circle problem for polygons is to use the generalized Voronoi diagram of the polygon's faces resp. the medial axis of the polygon. This approach works in a more general setting like polygons with holes, see this stackoverflow answer to a similar question.
Convex input.
The convexity of your input polygon, however, gives the problem more structure, which I would like to comment on. Consider the following convex input polygon (black), the Voronoi diagram (blue), and the maximum inscribed circle (green) centered on a Voronoi node.
The classical Voronoi-based solution is to (i) compute the Voronoi diagram and (ii) take the Voronoi node with largest clearance (i.e., distance to its defining faces).
The Voronoi diagram of a polygon with holes (i.e., the set of vertices and edges) can be computed in O(n log n) time, c.f. Fortune's algorithm (1986). Later Chin et alii (1999) gave an O(n) algorithm for the medial axis of a simple polygon.
For convex polygons, however, a time-optimal algorithm for Voronoi diagram that runs in O(n) time was already known in 1989 due to Aggarwal et alii. This algorithm follows basically the following idea: Consider the grey offset curves moving inwards at unit speed. If you project this movement into three-space where the z-axis is time you get a unit-slop roof over the polygon:
This roof model could also be characterized as follows: Put a half-space on each polygon edge at 45° slope with polygon (such that they contain the polygon) and intersect them all. So if you can quickly compute the intersect of half-spaces then you can also quickly compute Voronoi diagrams of convex polygons. Actually, for the maximum inscribed circle problem we do not need to go back to the Voronoi diagram but take the one peak of the roof, which marks the center of the maximum inscribed circle.
Now the half-spaces are dualized to points, and then the intersection of half-spaces corresponds the convex hull of its dual points. Aggarwal et al. now found an O(n) algorithm for the convex hull of points that stem from this setting.
A summary of this construction that leads to a Voronoi diagram algorithm for convex polyhedra in any dimension can be found in a blog article of mine.
Simple & fast implementation. A simpler algorithm to compute the Voronoi diagram is motivated by straight skeletons. For convex polygons the Voronoi diagram and the straight skeleton are the same.
The algorithm behind the straight-skeleton implementation Stalgo basically simulates the evolution of the wavefront structure (the grey offset curves). For convex polygons this reduces to finding the sequence of edges that collapse.
So a simple O(n log n) algorithm could look like this:
Construct a circular list of the polygon edges. Compute the collapse time of each edge during wavefront propagation, and insert this event into a priority queue.
Until the queue is empty: Take out the next edge-collapse event: Remove the edge from the circular structure and update the collapse times of the neighboring edges of the removed edge.
Actually, you can simplify the above algorithm further: You do not need to update edge collapses in the priority queue but simply insert new ones: Since the new collapse time of edges are strictly lower, you always get the right event first and dismiss the others and the queue is not growing larger than 2n. Hence, you do not compromise the O(n log n) time complexity.
For the maximum inscribed circle problem you can simplify the above algorithm even further: The Voronoi node (resp. straight skeleton node) you look for is due to the collapse of the final triangle at the end of the loop over the priority queue.
This algorithm should be quick in practice and only a few lines of code.
The last step can mean to select the minimum face of the triangle. Then rinse and repeat.

Find a set of points of a circle draped on a 3D height map

I have a height map of NxN values.
I would like to find, given a point A (the red dot), whose x and y coordinates are given (and z is known from the data, so A is a vertex of the surface) a set of points that lie on the circumference of the circle with center in A and radius R that are a good approximation of a circular "cloth" (in grey) draped on the imaginary surface described by the data points.
The sampling, the reciprocal distances between the set of points that I am trying to find, doesn't need to be uniform, but still I would like to find at least all the points that are an intersection of the edges of the mesh with the circle at distance R from A.
How to find this set of points?
Is this a known problem?
(source: keplero.com)
-- edit
The assumption that Jan is using is right: the samples form a regular rectangular or square grid (in the X-Y plane) aligned with [0,0]. But I would like to take the displacement in the Z direction into account to compute the distance. you can see the height map as a terrain, and the algorithm I am looking for as the instructions to give to an explorer that, traveling just on paths of given latitude or longitude, mark the points that are at distance R from A. Walking distance, that is taking into account all the Z displacements done so far. The explorer climbs and go down in the valleys too.
The trivial algorithm for this would be something like this. We know that given R, the maximum displacement on the x and y axis corresponds to a completely flat surface. If there is no slope, the x,y points will all be in the bounding square Ax-R < x < Ax+r and Ay-R
At this point, it would start traveling to the close cells, since if the perimeter enters the edge of one cell of the grid, it also have to exit that cell.
I reckon this is going to be quite difficult to solve in an exact fashion, so I would suggest trying the straightforward approach of simulating the paths that your explorers would take on the surface.
Given your starting point A and a travel distance d, calculate a circle of points P on the XY plane that are d from A.
For each of the points p in P, intersect the line segment A-p with your grid so that you end up with a sequence of points where the explorer crosses from one grid square to the next, in the order that this would happen if the explorer were travelling from A. These points should then be given a z-coordinate by interpolation from your grid data.
You can thus advance through this point sequence and keep track of the distance travelled so far. Eventually the target distance will be reached - adjust p to be at this point.
P now contains the perimeter that you're looking for. Adjust the sample fidelity (size of P) according to your needs.
Just to clarify - You have a triangulated surface in 3d and, for a given starting vertex Vi in the mesh you would like to find the set of vertices U that are reachable via paths along the surface (i.e. geodesics) with length Li <= R.
One approach would be to transform this to a graph-based problem:
Form the weighted, undirected graph G(V,E), where V is the set of vertices in the triangulated surface mesh and E is the set of edges in this mesh. The edge weight should be the Euclidean (3d) length of each edge. This graph is a discrete distance map - the distance "along the surface" between each adjacent vertex in the mesh.
Run a variant of Dijkstra's algorithm from the starting vertex Vi, only expanding paths with length Li that satisfy the constraint Li <= R. The set of vertices visited U, will be those that can be reached by the shortest (geodesic) path with Li <= R.
The accuracy of this approach should be related to the resolution of the surface mesh - as long as the surface curvature within each element is not too high the Euclidean edge length should be a good approximation to the actual geodesic distance, if not, the surface mesh should be refined in that area.
Hope this helps.

Largest circle inside a non-convex polygon

How can I find the largest circle that can fit inside a concave polygon?
A brute force algorithm is OK as long as it can handle polygons with ~50 vertices in real-time.
The key to solving this problem is first making an observation: the center of the largest circle that will fit inside an arbitrary polygon is the point that is:
Inside the polygon; and
Furthest from any point on the edges of the polygon.
Why? Because every point on the edge of a circle is equidistant from that center. By definition, the largest circle will have the largest radius and will touch the polygon on at least two points so if you find the point inside furthest from the polygon you've found the center of the circle.
This problem appears in geography and is solved iteratively to any arbitrary precision. Its called the Poles of Inaccessibility problem. See Poles of Inaccessibility: A Calculation Algorithm for the Remotest Places on Earth.
The basic algorithm works like this:
Define R as a rectilinear region from (xmin,ymin) to (xmax,ymax);
Divide R into an arbitrary number of points. The paper uses 21 as a heuristic (meaning divide the height and width by 20);
Clip any points that are outside the polygon;
For the remainder find the point that is furthest from any point on the edge;
From that point define a new R with smaller intervals and bounds and repeat from step 2 to get to any arbitrary precision answer. The paper reduces R by a factor of the square root of 2.
One note, How to test if a point is inside the polygon or not: The simplest solution to this part of the problem is to cast a ray to the right of the point. If it crosses an odd number of edges, it's within the polygon. If it's an even number, it's outside.
Also, as far as testing the distance to any edge there are two cases you need to consider:
The point is perpendicular to a point on that edge (within the bounds of the two vertices); or
It isn't.
(2) is easy. The distance to the edge is the minimum of the distances to the two vertices. For (1), the closest point on that edge will be the point that intersects the edge at a 90 degree angle starting from the point you're testing. See Distance of a Point to a Ray or Segment.
In case anyone is looking for a practical implementation, I designed a faster algorithm that solves this problem for a given precision and made it a JavaScript library. It's similar to the iterative grid algorithm described by #cletus, but it's guaranteed to obtain global optimum, and is also 20-40 times faster in practice.
Check it out: https://github.com/mapbox/polylabel
An O(n log(n)) algorithm:
Construct the Voronoi Diagram of the edges in P. This can be done with, for example, Fortunes algorithm.
For Voronoi nodes (points equidistant to three or more edges) inside P;
Find the node with the maximum distance to edges in P. This node is the centre of the maximum inscribed circle.
Summary: In theory, this can be done in O(n) time. In practice you can do it in O(n log n) time.
Generalized Voronoi diagrams.
If you consider the vertices and edges of the polygon as a set of sites and tessellate the interior into the "nearest neighbor cells" then you get the so-called (generalized) Voronoi diagram. The Voronoi diagram consists of nodes and edges connecting them. The clearance of a node is the distance to its defining polygon faces.
(Here the polygon even has holes; the principle still works.)
The key observation now is that the center of the maximum inscribed circle touches three faces (vertices or edges) of the polygon, and no other face can be closer. So the center has to lie on a Voronoi node, i.e, the node with the largest clearance.
In the example above the node that marks the center of the maximum inscribed circle touches two edges and a vertex of the polygon.
The medial axis, by the way, is the Voronoi diagram with those Voronoi edges removed that emanate from reflex vertices. Hence, the center of the maximum inscribed circle also lies on the medial axis.
Source: A blog article of mine that deals with generalizations of maximum inscribed circles at some point. There you can find more on Voronoi diagrams and their relation to maximum inscribed circles.
Algorithms & implementations.
You could actually compute the Voronoi diagram. A worst-case O(n log n) algorithm for points and segments is given by Fortune, A sweepline algorithm for Voronoi diagrams, SoCG'86. Held published the software package Vroni with an expected O(n log n) time complexity, which actually computes the maximum inscribed circle, too. And there seems to be an implementation in boost, too.
For simple polygons (i.e., without holes) a time-optimal algorithm that runs in O(n) time is due to Chin et al., Finding the Medial Axis of a Simple Polygon in Linear Time, 1999.
Brute force.
However, as you stated that you are fine with a brute-force algorithm: What about simply trying out all triplets of sites (vertices and edges). For each triplet you find candidate Voronoi nodes, i.e., equidistant loci to the three sites and check whether any other site would intersect the candidate maximum inscribed circle. If there is an intersection you dismiss the candidate. Take the greatest you can find over all triplets.
See chapter 3 in my Master thesis about more details on computing equidistant loci for three sites.
I implemented a piece of python code based on cv2 to get the maximum/largest inscribed circle inside mask/polygon/contours. It supports non-convex/hollow shape.
import cv2
import numpy as np
def get_test_mask():
# Create an image
r = 100
mask = np.zeros((4 * r, 4 * r), dtype=np.uint8)
# Create a sequence of points to make a contour
vert = [None] * 6
vert[0] = (3 * r // 2, int(1.34 * r))
vert[1] = (1 * r, 2 * r)
vert[2] = (3 * r // 2, int(2.866 * r))
vert[3] = (5 * r // 2, int(2.866 * r))
vert[4] = (3 * r, 2 * r)
vert[5] = (5 * r // 2, int(1.34 * r))
# Draw it in mask
for i in range(6):
cv2.line(mask, vert[i], vert[(i + 1) % 6], (255), 63)
return mask
mask = get_test_mask()
"""
Get the maximum/largest inscribed circle inside mask/polygon/contours.
Support non-convex/hollow shape
"""
dist_map = cv2.distanceTransform(mask, cv2.DIST_L2, cv2.DIST_MASK_PRECISE)
_, radius, _, center = cv2.minMaxLoc(dist_map)
result = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
cv2.circle(result, tuple(center), int(radius), (0, 0, 255), 2, cv2.LINE_8, 0)
# minEnclosingCircle directly by cv2
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[-2:]
center2, radius2 = cv2.minEnclosingCircle(np.concatenate(contours, 0))
cv2.circle(result, (int(center2[0]), int(center2[1])), int(radius2), (0, 255, 0,), 2)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
Red circle is max inscribed circle
Source: https://gist.github.com/DIYer22/f82dc329b27c2766b21bec4a563703cc
I used Straight Skeletons to place an image inside a polygon with three steps:
Find the straight skeleton using the Straight Skeleton algorithm (pic 1)
Base on the straight skeleton, find the largest circle (pic 2)
Draw the image inside that circle (pic 3)
Try it at: https://smartdiagram.com/simple-infographics-3d-charts-2/
An O(n log X) algorithm, where X depends on the precision you want.
Binary search for largest radius R for a circle:
At each iteration, for a given radius r, push each edge E, "inward" by R, to get E'. For each edge E', define half-plane H as the set of all points "inside" the the polygon (using E' as the boundary). Now, compute the intersection of all these half-planes E', which could be done in O(n) time. If the intersection is non-empty, then if you draw a circle with radius r using any point in the intersection as the center, it will be inside the given polygon.

Resources