Pathfinding with voronoi - algorithm

I have reached a dead-end with my university project and I can't find a way to solve. The problem is:
Given a circular robot (green circle) with radius r
I need to find a path (any path not the best) to the end point which is the blue dot.
image below
The obstacles are the red polygons and around them the cyan lines
represent the Minkowski sum.
The black dots represent the voronoi diagram.
The blue box around is the outside border
So first I though I should find the closer points to the start point (robot) and the end point of the voronoi diagram points. And those points are shown in the image (cyan dots).
Then I was thinking with some king of algorithm like the A* to search for the path for the cyan dots found above along the voronoi points, that way I will find the safest path sort of.
The problem is that I don't have a way of knowing which are the neighbors of each point in the voronoi diagram. Because as you can see in the some parts of the diagram there are big gaps.
So what do you suggest?
Thank you for your time.

Create a black and white image that represents your map. It should start as all black.
Render your obstacles as white.
Dilate the image using a circular filter the size of your circular robot.
Find the shortest path from A to B that only traverses black pixels.

The problem is that I don't have a way of knowing which are the neighbors of each point in the Voronoi diagram. Because as you can see in the some parts of the diagram there are big gaps.
There's probably a better solution, but here's a simple algorithm you could try:
Find (or set manually) the longest distance between "connected" points, D.
Make a table of distances between each pair of points of your Voronoi diagram, where that distance is less or equal to D.
Connect all points starting with shorter distances, except if path shorter than D already exists between them (to avoid unnecessary small loops and cutting corners).
Find closest point to your robot and closest point to your destination.
Run shortest path algorithm on the graph you built in step 3.

Related

Check if a Circle fits through a maze in non-quantized 2d space

I'm a high school student and I went to a coding competition recently and got this problem that I had no idea how to solve:
Given a maze enclosed in a 100x100 area, determine if a circle with a given radius could fit through the maze given the locations of all the walls. Walls will be defined as lines connecting two points within the space, and you will be given start and destination points for the circle. The circle must start with its center at the start point and touch the destination point for it to successfully fit through the maze. There will be a maximum of 20 walls. The radius of the circle and the locations of the walls can be "arbitrarily" precise. ("arbitrarily" for this case just means within far limits - let's say, up to a max of 10 digits after the decimal).
Here is an example. If this were the input:
Radius = 2.8
Start = (5,5), Destination = (95,95)
Walls (a wall connects each pair of points):
(20,0) to (27.5,22.6)
(27.5,22.6) to (55.1,35.5)
(55.1,35.5) to (80.3,80,4)
(80.3,80,4) to (95,63.9)
(1.7,25.8) to (17.5,53.2)
(17.5,53.2) to (56.4,69)
(56.4,69) to (67.9,90.6)
(85.6,98.94512) to (87.3,92.5)
then this (made on desmos) is what the maze would look like (the blue circle is just to show how big the circle is):
I would know how to solve the problem if it were in a quantized grid, but the exact locations of the walls and the radius of the circle can be arbitrarily precise. I've thought about using the "right-hand rule" to find a path, but I don't know how to implement that in a non-quantized space (nor am I very familiar with the method).
How would I go about solving this? Can someone point me to an algorithm, a link, some pseudocode, or just an intuition that could help me get an understanding of how I might solve this? Any help is appreciated. Thanks!
Thickennig/moving walls by r in each side like in the other answer (+1 btw) sounds simple but to code it its not trivial to do. For more info see
draw outline for some connected lines
The direction of normal in 2D is easy if dx,dy is line direction then (-dy,dx) and (dy,-dx) are normals to it ...
However I would encourage to do slower but safe and easier approach by computing the closest distance to wall for each vertex of the maze and close paths that are closer than 2r ...
Something like this:
So:
for each vertex
check all lines that does not belong to vertex path
compute perpendicular and min distance d to line and its vertexes
use the smallest d the distance can be computed easily see:
helix central axis angle
just look there for Perpendicular distance of any point P to AB so:
d = min
(
perpendicular_distance(line,vertex),
|line_vertex1-vertex|,
|line_vertex2-vertex|
)
if d<2r close the path. For example by adding a line that joins the wall its too close to tested vertex
ideally by joining tested vertex and the found closest point. Do not forget in such case to split the opposing wall line to two by the closest point so your graph algorithms still work...
As you can see this is O(n^2) instead of O(n) like in the other answer but its foul proof... enlarging polygons is not and in matters of fact its one of the hardest things in 2D geometry to code (IIRC even still open problem)...
It's quite a task and not easy to code, but here's a way that works:
Let r be the radius of the circle. That means that the center of the circle can't get within r of any obstacle.
Move the walls of your maze area in by r on each side.
Replace every wall endpoint with a circle of radius r.
Replace every wall with a rectangle of width 2r.
Now you don't need to worry about the circle -- only its center point, which must remain within the new boundaries and outside of any of the circles or rectangles you made from the walls.
Now, there is a path from the start to the end if they are in the same enclosed area. To find that out...
Cut the scene horizontally at every intersection and vertical maximum or minimum to create strips, with each strip divided into regions by a line or circular arc that passes all the way through it. A region does not connect direction to the regions to its left and right, but may connect to zero or more regions in the strips above and below it. The connections between regions form a graph.
Starting at the region containing the start point, run a BFS or DFS on this graph to see if you can reach the region containing the end point.

The shortest path between two points on a cuboid on its surface

I can't find a universal solution to "The Spider and the Fly Problem" (the shortest path between two points on a cuboid on its surface). Everybody solves a one specific case but what when two points can be anywhere?
My idea was to create an algorithm that considers various nets of a cuboid, calculates shortest paths on 2D and then returns the minimum but I have no idea for the algorithm to generate these grids (I guess hardcoding all combinations is not the best way).
Simplistic approach (only works where the points are on the same or adjacent faces)
Flatten the cube structure to 2d as follows...
Start with a face containing one of the two points. If this also contains the other point, you can stop there and the solution is trivial.
There are only 4 neighbouring faces. If any of them contain the other point, you can place that face adjoining the first, and plot the straight line.
Otherwise, then the points are on opposing faces. You need to try placing the final face adjoining each of the 4 neighbouring faces, and choose the shortest of the 4 alternatives. This will not always give the best solution, but it's not far off, and is cheap.
Generic approach
Jim Propp's surface distance conjecture is that For a centrally symmetric convex compact body, the greatest surface distance between two points is achieved only for pairs which are opposites through the centre. My conjecture based on that would be that the shortest distance is approximately where the plane made by the two points and the centre of the body meets the surface. So you simply need to find where that plane intersects the faces using 3d geometry, and use the faces that are crossed by the shorter of the two alternatives when looking at possible routes. If the plane runs along an edge of the cube (e.g. if the points are on opposite faces and are both between the centre of the face and the corner of the face, and those corners are linked by an edge) then routes through both faces should be considered, although I speculate they will be equivalent lengths.
This solution is more generic, and also satisfies scenarios where the points are on the same face, connected faces and opposite faces.
The only problem with this approach arises where the line between the two points passes through the centre of the body, which by definition means that the two points are exactly opposite each other, because that means the 3 points are in a straight line, so there isn't a plane...
I think this is a good question, for which the answer is not at all obvious. In the smooth realm, it is an extraordinarily difficult problem. Geodesics (shortest paths) on a sphere (which is a smooth analog of a cube) are easy to find. Geodesics on a biaxial ellipsoid (an ellipsoid of revolution; one cross section is a circle) are much harder to find. Finding geodesics on a triaxial ellipsoid (a smooth analog of a general cuboid) was a challenging unsolved problem in the first half of the 19th century. See the Wikipedia page.
On the other hand, geodesics on cuboid are made from straight line segments so are much simpler. But some of the difficulty of the problem remains.
You may be able to find some literature on the subject if you search for the term "net". A polyhedron cut along some edges so that it can be flattened is often called a "net". I was able to quickly find a site that claims (without proof) that there are just 11 different nets for a cub(oid). But I agree with you that hard coding all the variations is not the best way.
It's not even obvious to me that the approach using nets will work for all polyhedra. I think I see an argument that will work for cuboids, but for general polyhedra, even convex polyhedra, it is not known whether they must have even one net. See the Wikipedia page. I think a satisfying solution to the problem on cuboids should work more generally on polyhedra, and the net idea seems to be insufficiently general, in my view.
What I'm thinking might work is a dynamic programming solution, where you look at the different edges your path can pass through between the initial and final points. There is a hierarchy of edges (those on the starting face; those containing a vertex on the starting face; those on the faces adjacent to the starting face; etc.). For each point on each of those edges you can find the minimum distance to the start point, culminating in the minimum distance from the end point to the start point.
Another way to think about this is to use something akin to the reflection principle, except instead of reflections, we use rotations in space which rotate the polyhedron about one of its edges so that the other face adjacent to the edge becomes coplanar with the starting face. Then we don't have to worry about whether we have a good net or not. You just pick a sequence of edges so that the final point is eventually rotated onto the plane of the initial face. The sequence of edges is finite because any loop is not part of a minimal path. I'll think about how I might be able to communicate this idea better.
I solved the problem for cubes and cuboids by discretizing the cube edges, generating a big graph and solving graph shortest path problem. You can specify start point (sx, sy, 0), and algorithm will determine all shortest path to target points on top face (z = 1), here for 19 * 19 target points. Cube edges are divided into 100 parts. Graph with these settings has n=1558 vertices and m=464000(!) edges, inner loop of floyd_warshall_path() for updating shortest path distances is executed n³ = 3,781,833,112 times (takes less than 1 minute on Raspberry Pi400). Orange shortest paths flow through 3 cuboid faces, blue ones through 4. Algorithm generates OpenSCAD file as output. Details in this posting, all code in GitHub repo.
P.S:
I made experiments with 1 x 1 x 3 cuboid and was able to find examples where shortest path between two points needs to pass 5 faces. Code is submitted to GitHub repo, and details are in this forum posting.
Orange shortest paths are passing 3 faces, blue are passing 4 faces, and the new yellow shortest paths pass 5 faces! With "mirror" at bottom, allowing to see the bottom face with start point as well. This time cuboid edges are divided into 150 parts (149 inner vertices), and there are 49 * 49 top face target points for single start point on bottom face:
I implemented cuboid shortest paths completely different this time, no graph, and geometric distance calculations in 28 possible foldings of cuboid into plane, details in this new forum thread:
Efficient cuboid surface shortest path problem application
The much increased efficiency with all the sliders allows to change x/y coordinate of bottom face point, number of divisions in X/Y direction and which folding to display, with instantaneous display after any change. This allows to play with a cuboid and "see" how the shortest paths change (on top face as well as on side and bottom faces).
Scale to 50% size, 0.5fps animation shows the 6 foldings containing any shortest path. The animation corresponds to clockwise traversal of OpenSCAD 3D top face shown on the right.
With added top and bottom face view.
but for anyone still interested, this question was solved on stackxechange by "Intelligenti pauca" (with some nice diagrams): here is the original link
https://math.stackexchange.com/questions/3023721/finding-the-shortest-path-between-two-points-on-the-surface-of-a-cube
The "Simplistic approach" from "Richardissimo" was on the right track, you just need to check a few more cases.
Intelligenti pauca:
If the two points belong to adjacent faces, you have to check three
different possible unfoldings to find the shortest path. In diagram
below I represented the first point (red) and the second point (black)
in three possible relative positions: middle position occurs when the
path goes through the common edge, in the other cases the path
traverses one of the faces adjacent to both faces. The other possible
positions are clearly longer than these.
image1
If the two points belong to opposite faces, then 12 different possible
positions have to be checked: see diagram below.
image2
After mapping the points like this you can calculate the distances like normal on a plane an have min(possible distances) as your shortest path-length.

Having the final Thiessen polygons, is it possible to find the initial set of points?

I'm trying to find a way to reverse the Voronoi algorithm.
Basically, having some connected shapes which mostly consist of triangles and squares, I'm trying to find the set of points which, by using the Voronoi algorithm would recreate the initial shapes.
Introduction.
This problem has been solved in a paper by Biedl et al. in 2013 after a partial solution by Ash and Boker in 1985. In case your Voronoi nodes are all of odd degree then the algorithm by Ash and Bolker works for you.
First of all note that there might not be the point set but many point sets all having the same Voronoi diagram you ask for. For instance, consider this picture
taken from this website. The red point set and the blue point set give you the same black Voronoi diagram. (And, by the way, the straight skeletons of the red and blue polygon coincide with the Voronoi diagrams of the point sets as well.)
Overview of the algorithm.
The rough idea is the following. Assume an oracle told you one candidate point in a Voronoi cell. Then you can mirror this point to neighboring Voronoi cells by the common edges between the neighboring cells, and keep on propagating.
But there could be troubles: The mirrored point may lie outside the neighboring cell. Also if you consider a Voronoi node and the incident cells then you can keep propagating the point around one cycle by the incident Voronoi edges, but you may not end up at the original point again.
So what the paper does is the following:
It gives sufficient and necessary conditions for your input to form a Voronoi diagram.
It tells you how to choose a valid starting point if such a point exists. Actually, it gives you set of all possible starting points.
The second part works roughly as follows: For each Voronoi cell one knows a "region" where the point has to lie by investigating the Voronoi nodes of the cell. Then take a spanning tree of the dual graph of the Voronoi diagram and choose an arbitrary root. For every cell you have a unique "mirroring path" to the "root cell". Apply the mirroring sequences of the regions mentioned above and intersect the mirror images.
The intersection is the set of all possible starting points. If it is empty then your input was not a Voronoi diagram.
Further simplification.
In case your Voronoi nodes are of odd degree then the problem is much simpler. Consider Fig-4 in the paper by Biedl et al. to find out for each node the lines where the points must lie on. If a Voronoi cell has two nodes of odd degree then you can intersect these lines and get the single possible candidate point. You can do this for every Voronoi cell.
Wouldn't finding the centroid of every triangle give you a point that is by definition, as far as possible from the other points.

Algorithm to calculate the shortest path between two points on the surface of a 3D mesh

I am looking for an algorithm to calculate the following:
I have:
A 3D triangle mesh. The triangles do not necessarily lie in one plane. The angle between the norm vectors of two neighbouring triangles is less then 90 degrees.
Two points. The two points lie either on an edge of the triangle mesh or inside a triangle of the mesh.
I need to calculate the polyline which represents the shortest path between the two points on the mesh.
What is the simplest and/or most effective strategy to do this?
As it stands, your problem is not well defined; there can be many solutions depending on the direction used to "project" the line segment onto the mesh.
Once you have chosen the direction of projection, flatten the mesh onto a plane perpendicular to the direction of projection. At this point, your mesh is a collection of 2d edges (line segments); just determine the intersection (if any) of each edge with your target line segment.
Edit:
The updated question is now well defined. Since my answer to the original question (above) has been marked as accepted, presumably that means the information given in the comments below are actually what was really being "accepted" for the update question. I'll summarize:
A google search of "shortest distance on 3d mesh" turns up some relevant information, like Shortest Path Approximation on Triangulated Meshes
Also, see: https://stackoverflow.com/a/10389377/294949 -- danh
Since your start/end points potentially lie anywhere on the mesh (not restricted to vertices) I guess you are searching for the geodesic shortest path (not Dikstra shortest path following edges). A nice algorithm is implemented in geometry-central: http://geometry-central.net/surface/algorithms/flip_geodesics/
The algorithm is described in the paper "You Can Find Geodesic Paths in Triangle Meshes by Just Flipping Edges".
A standard approach to this task of finding the shortest path polyline (or geodesic) on the surface of triangular mesh between two given points consists of two steps:
Find a path approximation between two points
Iteratively adjust it to make it locally shortest everywhere.
The first step (path approximation) can be computed, for example, using
Dijkstra algorithm, which considers only paths along mesh edges (no crossing of mesh triangles),
Or some variations of Dijkstra algorithm, better suited for near planar surfaces like A*-search,
Or it can be Fast marching method, which can find also the paths crossing the triangles, however not guaranteed to produce a geodesic line.
The next step is iterative adjustment of the approximate path till it becomes truly locally shortest. Some recent articles are really promising here, like Just Flipping Edges. But it requires to construct a path network from the original mesh before operating, so it can be really expensive if your task is just to find one shortest path on the mesh.
A more classical way is to consider every piece of current path approximation between it enters two consecutive vertices, and unfold the strip of crossed triangles on plane. Then find the shortest path in the planar strip, which is a task that can be solved exactly in a linear time, for example by Shortest Paths in Polygons method by Wolfgang Mulzer. The crossing of this line with the edges will give the shortest path on the mesh in between two vertices.
Then for every vertex on the path approximation, two walks around this vertex are evaluated using same unfolding in hope a path around will be shorter then the path exactly via the vertex. The last steps are repeated till convergence.
Below is an example of geodesic path on a mesh with 2 million triangles:
Left - from the application MeshInspector: the time of iterative adjustment is highlighted in green and it is only a small fraction of total time.
Right - the picture from Just Flipping Edges article, where total time is not given, but it is presumably even higher due to the necessity to construct path network from the mesh.

Algorithm for a "Blob" Border

I have several 2 dimensional circles that I want to draw a border around. I've done this using a convex hull before, but my goal is to make the border almost like a surrounding "blob". I attached a picture to show what I mean.
Essentially, I want the border to outline the circles, and be pulled slightly into the middle of the area if no circles are present. The center shape shows my current train of thought -- create normal lines for each circle, and somehow merge them into a complete shape.
Summed up, I have 2 questions:
1. Are there any existing algorithms to do this?
2. If not, are there any algorithms that would help me merge the circle outlines into a single larger path?
Thank you!
"Everything You Always Wanted to Know About Alpha Shapes But Were Afraid to Ask" is for you http://cgm.cs.mcgill.ca/~godfried/teaching/projects97/belair/alpha.html
One way to get this border could be to simply compute the distance to the centers of circles: for a given point this distance is the minimum of the distances from this point to all the centers of the given circles. Then sample this distance function over a regular grid. And finally extract the f-level of this function as a collection of polylines with an isocurve extraction algorithm (like Marching Squares). f should be the radius of the circles augmented with the desired margin.

Resources