Ther is an example on how to find one nearest neighbor yet how to find all in a radious (or a box placing search begining into its centre if possible)?
Related
I am looking for an algorithm that can do efficient search in a grid.
I have a large array which includes all the centroid points (x,y,z)
Now for a given location (xp,yp,zp) I want to find the closest centroid to that p location.
Currently I am doing a brute force search which basically for each point p I go through all points, calculate the distance to location p and by this find out which centroid that is.
I know that octree search and kd-tree might help but not too sure how to tackle it or which one would be better.
I would you a spatial index, such as the kd-tree or quadtree/octree (which you suggested) or maybe an R-Tree based solution.
Put all your centroids into the index. Usually you can associated any point in the index with some additional data, so if you need that, you could provide a back-treference into the grids, for example grid coordinates).
Finding the nearest point in the index should be very fast. The returned data then allows you to go back into the grid.
In a way, a quadtree/octree is in itself nothing but a discretizing grid that get finer if the point density increases. The difference to a grid is that it is hierarchical and that empty areas are not stored at all.
Say a number of points are arrayed on the edge of a circle. Starting from the centre of the circle, how do I find what direction I should move in to maximize my distance from the red closest point? I want to get away from the points in red. Another way of framing the question is to find a new point on the circle that maximizes the distance from it the nearest red point. Below are some examples, with my desired directions in blue, and points I want to get away from in red.
Sort all points on the circle into a list, clockwise
pair each point with its successor, and the last point with the first one
find the pair with the greatest angular distance (ca. 200° clockwise between the 2nd and 3th point in the first pic)
The desired direction is halfway between those two points ( ca. 100° after the 2nd point in the first pic)
Concerning tree searching algorithms, particularly quad-tree and r-tree, how do they account for edge errors when finding nearest neighbors. I'm not good at explaining this with words so I made some pictures.
For the picture the input coordinate to find the nearest neighbor is green, what I would assume end up being the "found" nearest neighbor is red. The actual nearest neighbor is blue.
In this quad-tree, the blue lower-right quadrant would be searched in with only that one red point while in actuality, the input coordinate (green) is so close to the edge it's actually closer to the blue point.
Similar with an R-tree if the coordinate is within one rectangle but so close to the edge it's closer to a point in another rectangle like below, where white dot is given coordinate:
It's wholly within the red box but closer to a point in the magenta box.
In both cases it is necessary to do a fine-grain distance check between elements - the boxes or divisions just help find candidates for the real distance check.
A way to look at it is, use the boxes to tell you what NOT to check. If an entire box is farther away than something you already know, you don't need to check anything in that box. If some of the box is close, better check the elements in it.
If you would bother to read the R-tree publication...
It uses a minimum distance, of the query point to a neighboring page.
If mindist(query, rectangle) <= dist(query, known neighbor) then the search needs to continue in the other rectangle, because there could be a better neighbor there.
It's actually quite straightforward, and should be explained in any book on R-trees and similar indexes.
I have xy grid, where points have whole-numbered, positive coordinates. These points are "neighbours" if both their x and y coordinates differ by less than 2 - they are simply next to each other.
In this grid, I have found path that encloses some area. Every point in the path is neighbour to the previous point and the next point, so it is sorted like you walked around the enclosed area. It is also shortest path around that enclosed area, so there are no steps back and forth. The enclosed area does not need to be convex, so when you connect two random points on the path with one line, that line can lie completely out of that area.
The problem is, I need to find at least one point in enclosed area, that is neighbour to any point in enclosing path.
It might sound easy, but I have not found solid algorithm to determine it.
* I'm sorry, I did not explain that well enough. There are no "empty parts" in enclosed area. If there are three points in enclosed area, the path around is the smallest path that captures those three points. In this picture, red path is shortest, black is too long and I never need to detect those.
Observations to check that I understand the question:
It's possible that there are no such interior points.
Given that consecutive path point are neighbors, the connection
angles will be at multiples of 45°.
The basic idea is to walk the path and keep track of interior and exterior neighbors.
To determine which side is the interior, walk the path and keep track of the cumulative turn angle. The final amount will be 360° or -360° which will indicate the interior is on the left or the right, depending on which way you defined positive and negative angles.
During that first pass, also collect a hash set of the points on the path, onPathPoints.
Initialize two other hash sets to empty: exteriorPoints and possibleInteriorPoints.
Walk the path and for each point:
a. categorize the 8 neighbors as on-path, interior-side or exterior-side based on the relative positions of the previous and next points on the path.
b. for each point in onPathPoints, ignore it.
c. for any point on the interior side and distance 1 away, return that point as the result.
d. for each points on the interior side with distance > 1 (diagonal neighbor), add it to possibleInteriorPoints.
e. for each point on the exterior side and distance 1 away, add it to exteriorPoints.
At the end of the walk, remove from possibleInteriorPoints any point in exteriorPoints (set subtraction). Return any point remaining in possibleInteriorPoints as an interior point.
Otherwise, there are no interior points.
The possibleInteriorPoints represent diagonally neighboring points that are in the interior unless the path loops back between the original point and it (in which case it will be an exterior point to the new path part.
For example in the image below, when visiting (2,2) and going toward (3,3) the interior is on the right. (3,1) is a possible interior point, but later in the walk while visiting (4,1), (3,1) is noted to be an exterior point and so would get removed from possibleInteriorPoints.
Technically, in this example the algorithm would have stopped when visiting (4,3) and noting (4,2) as an interior point at distance 1.
I have a set of 2D points, unorganized, and I want to find the "contour" of this set (not the convex hull). I can't use alpha shapes because I have a speed objective (less than 10ms on an average computer).
My first approach was to compute a grid and find the outline squares (squares which have an empty square as a neighbor). So I think I downsized efficiently my numbers of points (from 22000 to 3000 roughly). But I still need to refine this new set.
My question is : how do I find the real outlines points among my green points ?
After a weekend full of reflexions, I may have found a convenient solution.
So we need a grid, we need to fill it with our points, no difficulty here.
We have to decide which squares are considered as "Contour". Our criteria is : at least one empty neighbor and at least 3 non empty neighbors.
We lack connectivity information. So we choose a "Contour" square which as 2 "Contour" neighbors or less. We then pick one of the neighbor. From that, we can start the expansion. We just circle around the current square to find the next "Contour" square, knowing the previous "Contour" squares. Our contour criteria prevent us from a dead end.
We now have vectors of connected squares, and normally if our shape doesn't have a hole, only one vector of connected squares !
Now for each square, we need to find the best point for the contour. We select the one which is farther from the barycenter of our plane. It works for most of the shapes. Another technique is to compute the barycenter of the empty neighbors of the selected square and choose the nearest point.
The red points are the contour of the green one. The technique used is the plane barycenter one.
For a set of 28000 points, this techniques take 8 ms. CGAL's Alpha shapes would take an average 125 ms for 28000 points.
PS : I hope I made myself clear, English is not my mothertongue :s
You really should use the alpha shapes. Maybe use only green points as inputs of the alpha alpha algorithm.