Here is a picture to illustrate the problem:
In the picture there are some feature points shown as blue crosses. I know the coordinate (x,y) for all of the features. Now I want to query which features are inside the circle area (green circle). In practice, there are around 500 features and 300 queries (300 different circles, different centers and radius). I know the parameters (position, radius) of circles. Is there any good algorithm which can do this task?
Current I have two ideas.
Most stupid one, just iterate through all of the features in each
query. This is slower.
A rough idea. Separate the whole picture to some sub-pictures. Put features into a tree structure according to sub-pictures, if features in the same sub-pictures, then put in the same leaf. In each query, find out which sub-picture are covered by the circle and check all of the feature in these sub-pictures.
Does anyone out there have any better ideas?
The most common way is to put the points into a K-D tree or similar: https://en.wikipedia.org/wiki/K-d_tree
To find the points within a circle, you get the list of points in order of increasing distance from the center, and stop when the distance exceeds the circle radius.
To get list of points in order of increasing distance, you can use a priority queue that can hold both points and internal nodes of the tree, which lets you remove them in order of distance.
For points (leaves), the distance is just the distance of the point from the center point. For internal nodes, the distance is the smallest distance from the center point to any point that could possibly be in that node.
To search, you just put the root of the tree in the priority queue, and repeat:
Remove the head of the priority queue;
If the head of the queue was a point, then it is the closest point in the tree that you have not yet returned. You know this, because if any internal node could possibly have a closer point, then it would have been returned first from the priority queue;
If the head of the queue was an internal node, then put its children back into the queue
This will produce all the points in the tree in order of increasing distance from the center point.
Related
I have a list of coordinates and I need to find the closest coordinate to a specific point which I'll call P.
At first I tried to just calculate the distance from each coordinate to P, but this is too slow.
I then tried to store these coordinates as a quad-tree, find the leaf node that contains P, then find the closest coordinate in that leaf by comparing distances of every coordinate to P. This gives a good approximation for the closest coordinate, but can be wrong sometimes. (when a coordinate is outside the leaf node, but closer). I've also tried searching through the leaf node's parent, but while that makes the search more accurate, it doesn't make it perfect.
If it is possible for this to be done with a quad-tree, please let me know how, otherwise, what other methods/data structures could I used that are reasonably efficient, or is it even possible to do this perfectly in an efficient manner?
Try "loose quadtree". It does not have a fixed volume per node. So it can adjust each node's bounding volume to adapt to the items added.
If you don't like quadtree's traversing performance and if your objects are just points, adaptive-grid can perform fast or very close to O(N). But memory-wise, loose quadtree would be better.
There is an algorithm by Hjaltason and Samet described in their paper "Distance browsing in spatial databases". It can easily be applied to quadtrees, I have an implementation here.
Basically, you maintain a sorted list of object, the list is sorted by distance (closest first), and the objects are either point in your tree (you call the coordinates) or nodes in the tree (distance to closest corner, or distance=0 if they overlap with you search point).
You start adding all nodes that overlap with your search point, and add all points and subnodes in these points.
Then you simply return points from the top of the list until you have as many closest points as you want. If a node is at the top of the list, add points/subnodes from that node to the list and check the top of the list again. Repeat.
yes you can find the closest coordinate inside a quad-tree even when it is not directly inside the leaf. in order to do that, you can do the following search algorithm :
search the closest position inside the quad-tree.
take its distance from your initial position
search all the nodes inside this bounding box from your root node
return the closest node from all the nodes inside this bounding box
however, this is a very basic algorithm with no performance optimizations. among other things :
if the distance calculated in 2. is less than the distance to the border of the tree node, then you don't need to do 3 or 4. (or you can take a node that is not the root node)
also, 3 and 4 could be simplified into a single algorithm that only search inside the tree with the distance to the closest node as the bounding box.
And you could also sort the way you search for the nodes inside the bounding box by beginning to search for the nodes closest to your position first.
However, I have not made complexity calculation, but you should expect a worst case scenario on one node that is as bad if not worst than normal, but in general you should get a pretty decent speed up all the while being error free.
I have a plane with a bunch of points (x, y coordinates) scattered all over, and I need to encircle each of them within as few circles of the same radius as possible. Something like this:
To get a result of a list of center points for the circles that will enclose each of those points, like this:
So the data would be a list of points and the fixed radius for the circles to enclose them, and the result would be a list of as few center points as possible to enclose each.
I'm currently working in Lua, so if there's a library that has functions to achieve this, or if someone knows an algorithm or can point me in the right direction mathematically, that'd be great!
Create an adjacency matrix for the graph of nodes (nodes are connected only if they are close enough), and you can easily see which is the best way to group them.
Just group them starting from the node (vertex) that has the highest degree.
I'll add a code when I'm at a computer.
What is the best way of combining overlapping circles into polygons?
I am given a list of centre points of circles with a fixed diameter.
I need to join any overlapping circles together and output a list of points in the resulting polygon.
This seems like a fairly common problem (GIS systems, vectors, etc.). This is possible to do through the Google Maps API but I am looking for the actual algorithm.
I have tried to solve this problem by calculating points around each circle.
Then removing any points located inside any circle.
This gives me the correct list of points in the desired polygon.
However, the order of the points is a problem with this solution. Each circle has its points stored in an array. To merge them correctly with 2 overlapping circles is relatively straight forward. However, when dealing with multiple overlapping circles it gets complicated.
Hopefully you have some ideas to either make this solution work or of another algorithm that will achieve the desired result.
Thanks in advance!
You should be able to use an appraoch like the following:
First, identify circles that belong to the same group of overlapping circles. Obviously, two circles overlap if the absolute distance of their centres is less than their combined radii. For each circle, store the circles it itersecs with in a hashmap/dictionary. (You can extend this to entire groups of circles using the union-find algorithm, or disjoint sets, but this is not really needed.)
When creating the points belonging to one circle, memorize the left and right neighbor of each point. You get this for free by just storing them in an ordered array.
Remove the "inner" points, i.e. those that are closer than one radius to any of the centres of the circles intersecting the first circle.
Mark the neighbors to those inner points that were not removed the "loose ends" of the circles.
Connect the points that were not removed, including the loose ends, to their original left and right neighbors.
For each loose end point, find the closest loose end of a different circle in the same group and connect them.
Here's a picture to illustrate the approach.
Red dots are "inner" points that are removed
Blue dots are "loose ends" by being neighbors to "inner" points; each "loose end" has another "loose end" of a different circle that's less than two "point-distances" away
Green dots can easily be connected to their neighbors (including the "loose ends") by the order in which they were arranged around the circle.
You can further decrease the number of possible combinations by distinguishing left and right loose ends, and using the fact that each left loose end of one circle has to be connected to a right loose end of another circle. For n circles in a group, that leaves just (n-1)! ways to connect those circles, irrespective of the number of points per circle.
And even this can be reduced further if you consider only those circles in the group that actually intersect the circle with the loose end (just store those in a hashmap/dictionary). So if you have n circles that on average intersect with k other circles, then there are only n*k possible combinations.
You could also use the fact that the other loose end can not be farther away than two times the distance between two point on the circle. Let's call this distance d, then you can create a spatial map with resolution d (e.g. a hashmap, or just a 2D array) and assign each loose end to cells in that map, then the other loose end must be in the same of one of the surrounding cells of the first loose end.
Thus, the number of ways in which points can be connected to each other is greatly reduced (in particular, the way they are connected in your final image would not be allowed to begin with): This should be doable even with brute force unless you have lots of overlapping circles in the same group, and there are smarter algorithms for nearest-neighbor search that you can use.
Update: Reviewing this answer after some time, it seems that you can determine the matching pairs of "loose end" points rather easily: Say you have a "right" loose end in circle A, then the matching "left" loose end has to belong to the circle whose radius overlapped the next "inner" point to the first "loose end". So if you store that relation in another map, you can immediately determine the matching loose end. (If an inner point is overlapped by multiple other circles, the map should contain the circle that overlaps it the most.)
Here's a sketch of an O(n log n)-time algorithm.
Use your favorite algorithm/library to compute a Delaunay triangulation on the circle centers.
Delete the edges between circles that do not overlap.
Walk around the infinite face of each connected component. This is easy to do with a doubly connected edge list representation, where the ordering of the edge lists is used to indicate the topology of the planar graph. Every half-edge on this boundary turns into a vertex where an arc segment belonging to its tail point ends and an arc segment belonging to its head point begins.
(Optional) Approximate each arc segment by a polygonal line.
If anyone from Google is reading this, please note that I have not looked at the relevant code.
I am building a graph editor in C# where the user can place nodes and then connect them with either a directed or undirected edge. When finished, an A* pathfinding algorithm determines the best path between two nodes.
What I have: A Node class with an x, y, list of connected nodes and F, G and H scores.
An Edge class with a Start, Finish and whether or not it is directed.
A Graph class which contains a list of Nodes and Edges as well as the A* algorithm
Right now when a user wants to select a node or an edge, the mouse position gets recorded and I iterate through every node and edge to determine whether it should be selected. This is obviously slow. I was thinking I can implement a QuadTree for my nodes to speed it up however what can I do to speed up edge selection?
Since users are "drawing" these graphs I would assume they include a number of nodes and edges that humans would likely be able to generate (say 1-5k max?). Just store both in the same QuadTree (assuming you already have one written).
You can easily extend a classic QuadTree into a PMR QuadTree which adds splitting criteria based on the number of line segments crossing through them. I've written a hybrid PR/PMR QuadTree which supported bucketing both points and lines, and in reality it worked with a high enough performance for 10-50k moving objects (rebalancing buckets!).
So your problem is that the person has already drawn a set of nodes and edges, and you'd like to make the test to figure out which edge was clicked on much faster.
Well an edge is a line segment. For the purpose of filtering down to a small number of possible candidate edges, there is no harm in extending edges into lines. Even if you have a large number of edges, only a small number will pass close to a given point so iterating through those won't be bad.
Now divide edges into two groups. Vertical, and not vertical. You can store the vertical edges in a sorted datastructure and easily test which vertical lines are close to any given point.
The not vertical ones are more tricky. For them you can draw vertical boundaries to the left and right of the region where your nodes can be placed, and then store each line as the pair of heights at which the line intersects those lines. And you can store those pairs in a QuadTree. You can add to this QuadTree logic to be able to take a point, and search through the QuadTree for all lines passing within a certain distance of that point. (The idea is that at any point in the QuadTree you can construct a pair of bounding lines for all of the lines below that point. If your point is not between those lines, or close to them, you can skip that section of the tree.)
I think you have all the ingredients already.
Here's a suggestion:
Index all your edges in a spatial data structure (could be QuadTree, R-Tree etc.). Every edge should be indexed using its bounding box.
Record the mouse position.
Search for the most specific rectangle containing your mouse position.
This rectangle should have one or more edges/nodes; Iterate through them, according to the needed mode.
(The tricky part): If the user has not indicated any edge from the most specific rectangle, you should go up one level and iterate over the edges included in this level. Maybe you can do without this.
This should be faster.
In my app, the GPS picks the location of the vehicle. It is then supposed to put markers at all points where the vehicle could be if it drives for 1 KM in any direction (note that the roads may fork many times within his 1KM reach).
Can someone suggest me how to do this? Thanks in advance.
This is a very tricky problem to solve with the Google Maps API. The following is one method that you may want to consider:
You can easily calculate a bounding circle of 1km around your GPS point, and it is also easy to calculate points that fall on the circumference of this circle, for any angle. This distance will be "as the crow files" and not the actual road distance, but you may want to check out the following Stack Overflow post for a concrete implementation of this:
How to calculate the latlng of a point a certain distance away from another?
Screenshot with markers at 20 degree intervals on a bounding circle with a 1km radius:
removed dead ImageShack link - How to calculate the latlng of a point a certain distance away from another?
There is also a trick to snap these points to the nearest street. You can check out Mike Williams' Snap point to street examples for a good implementation of this.
Calculating the road distance from your GPS point to each snapped road point could be done with the directions service of the Google Maps API. Note that this will only work in countries that support directions in Google Maps, but more importantly, the road distance will almost always be greater than 1km, because our bounding circle has a 1km radius "as the crow flies". However if you can work with approximate information, this may already be one possible solution.
You can also consider starting with the above solution (1km bounding circle, calculate x points on the circumference, and snap them to the closest road), then calculate the road distance of each path (from your GPS point to each snapped point), and then you can repeat this this recursively for each path, each time using a smaller bounding circle, until you reach a road distance close to 1km. You can decrease the bounding circle in each recursion, in proportion to the error margin, to make your algorithm more efficient.
UPDATE:
I found a very neat implementation which appears to be using a similar method to the one I described above:
Driving Radius (Multiple destinations)
Note how you can change the interval of degrees from the top. With a wide interval you'll get fast results, but you could easily miss a few routes.
Screenshot:
removed dead ImageShack link - Driving Radius
Natural brute force algorithm is to build a list of all possible nodes taking into account each possible decision on every crossroad.
I doubt that within 1km you would get more then 10 crossroads on average and assuming avg of 3 choices on a crossroad you would end up with 3^10 - around 59,049 end nodes (notice that you need to have 10 crossroads on every branch of the road to reach the full number).
In reality the number would go down and I would assume getting to the same node by different route would not be uncommon, especially in cities.
This approach would give you an exact answer (providing you have good street map as input). It is potential time, but the n does not seem to be that high, so it might be practical.
Further improvements and optimizations might be possible depending on what do you need these nodes for (or which kind of scenarios you would consider similar enough to prune them).
Elaborating a bit on Daniel's approach above, you want to first find all the point within a straight line radius from your origin. That's your starting set of nodes. Now include ALL edges incident to those nodes and other nodes in your starting set. Now check that the nodes are connected and that there aren't any nodes out there floating around that you can't reach. Now create a "shortest path tree" starting from your vehicle node.
The tree will give you the shortest paths from your starting node to all other nodes. Note that if you start by creating paths at the furthest nodes, any sub-paths are also shortest paths to those nodes along the way. Make sure to label those nodes on sub-paths as you continue so you don't need to compute them. Worst case scenario, you need to develop a shortest path for all nodes, but in practice this should take much less time.
List all possible nodes taking into account each possible decision on every crossroad
(But how to do it automatically?
Use Dijkstra`s algorithm to find closes route to all points.
Visualize data.
(That is a little bit tricky, because there can be an unreachable areas inside reachable area.