Which of these (k-d tree, r-tree) would be suitable for searching and indexing polygon.
My usecase is that i have been given some lat-long points (min 3 for a valid polygon) and from these points i need to find the polygon which is the smallest one.
By smallest i mean that if there is a polygon inside another polygon, then the inside polygon should be returned.
And if polygon overlap, they should not be chosen.
I think finding the location and then the area might be tried but i am not sure.
I would also like get some idea about which data structure would be useful. I think postgis uses R-tree indexing.
R-tree is good for polygons, because it works on bounding boxes, including all the points for a particular polygon. You can easily find candidate polygons and then do a fine-grain check for overlap, area, etc.
Kd-tree works on points, so polygons would be hard to index.
R-tree also supports adding and removing data items. As I recall a kd-tree, once built, is hard to update for new or changing data.
Related
I am currently wondering if there is a common algorithm to check whether a set of plane polygones, not nescessarily triangles, contruct a watertight polyhedra. Each polygon has an oriantation (normal vector). A simple solution would just be to say yes or no. A more advanced version would be to point out the edges, where the polyhedron is "open". I am not really interesed on how to close to polyhedra.
I would like to point out, that my "holes" are not nescessarily small, e.g., one face of a cube might be missing. Thus, the "undersampling correction" algorithms dont seem to be the correct approach. Furthermore, I am talking of about 100 - 1000, not 1000000 polygons, so computation time should not really be a problem.
Any hints or tips?
kind regards,
curator
I believe you can use a simple topological test -- count the number of times each edge appears in the full list of polygons.
If the set of polygons define the surface of a closed volume, each edge should have count>=2, indicating that each edge is shared by (at least) two adjacent polygons. If the surface is manifold count==2 exactly.
Edges with count==1 indicate open regions of the surface.
The above answer does not cover many cases. A more correct (but not necessarily complete: I wouldn't know) algorithm is to ensure that every edge of every polygon (or of the mesh/polyhedron) has an even number of faces connected to it. Consider the following mesh:
The segment (line) between the closest vertex and the one below is attached to 3 faces (one one of the outer triangle and two of the inner triangle), which is greater than two faces. However this is clearly not closed.
Say I have a 2D plane, covered with polygons (identified as an array of vertexes), analogous to:
Lets say I also have a point with coordinates on this plane, what is the easiest method to return which of the polygons the point is present in?
Although this example lists 4 polygons, it would be simple to run a check on each polygon to see if the point is within it, but I am building a system that presently has about 150 polygons, and could extend up to thousands, so doing it that way could become very slow.
So, are there any solutions to doing this that do not incur iterating through all available polygons, and checking if the point is present?
You can use a kd-tree or a r-tree. It can reduces the search space. You can also look for a quadtree. You can choose the quad size to fit the polygons and to minimize overlapping bounding boxes.
I have given the coordinates of 1000 triangles on a plane (triangle number (T0001-T1000) and its coordinates (x1,y1) (x2,y2),(x3,y3)). Now, for a given point P(x,y), I need to find a triangle which contains the point P.
One option might be to check all the triangles and find the triangle that contain P. But, I am looking for efficient solution for this problem.
You are going to have to check every triangle at some point during the execution of your program. That's obvious right? If you want to maximize the efficiency of this calculation then you are going to create some kind of cache data structure. The details of the data structure depend on your application. For example: How often do the triangles change? How often do you need to calculate where a point is?
One way to make the cache would be this: Divide your plane in to a finite grid of boxes. For each box in the grid, store a list of the triangles that might intersect with the box.
Then when you need to find out which triangles your point is inside of, you would first figure out which box it is in (this would be O(1) time because you just look at the coordinates) and then look at the triangles in the triangle list for that box.
Several different ways you could search through your triangles. I would start by eliminating impossibilities.
Find a lowest left corner for each triangle and eliminate any that lie above and/or to the right of your point. continue search with the other triangles and you should eliminate the vast majority of the original triangles.
Take what you have left and use the polar coordinate system to gather the rest of the needed information based on angles between the corners and the point (java does have some tools for this, I do not know about other languages).
Some things to look at would be convex hull (different but somewhat helpful), Bernoullies triangles, and some methods for sorting would probably be helpful.
I have a relational database where each entry is marked as a dot with latitude/longitude coordinates. I give the user the ability to mark an arbitrary polygon on a map, and want to return all entries that are within the polygonal shape.
What would be the best way to achieve this?
Also, it might be worth to point out that small errors are ok (ie. if there is an effective way to turn the polygon into a set of rectangles, then that is fine).
Use spatial extensions, most databases have this.
In MySql you can only use them with MyISAM tables which are not transactional.
http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html
One way to quickly cut down on the number of points to consider is to compute the bounding rectangle for the polygon (i.e. just min-x, min-y, max-x, max-y of the points in the polygon), and then select for points within the bounding rectangle (i.e. where x is between min-x and max-x and same for y).
Of course not all these points are necessarily inside the polygon, but now you can hone it with code.
An old hack:
Count the number of times a line connecting <point far away> to <point in question> crosses any of the bounding segments of the polygon.
Even numbers mean the point is outside the polygon
Odd numbers mean it is inside the polygon
What is a good algorithm for reducing the number of vertices in a polygon without changing the way it looks very much?
Input: A polygon, represented as a list of points, with way too many verticies: raw input from the mouse, for example.
Output: A polygon with much fewer verticies that still looks a lot like the original: something usable for collision detection, for example (not necessarily convex).
Edit: The solution to this would be similar to finding a multi-segmented line of best fit on a graph. It's called Segmented Least Squares in my algorithms book.
Edit2: The Douglas Peucker Algorithm is what I really want.
Edit: Oh look, Simplifying Polygons
You mentioned collision detection. You could go really simple and calculate a bounding convex hull around it.
If you cared about the concave areas, you can calculate a concave hull by taking the centroid of your polygon, and choosing a point to start. From the starting point rotate around the centroid, finding each vertex you want to keep, and assigning that as the next vertex in the bounding hull. The complexity of the algorithm would come in how you determined which vertices to keep, but I'm sure you thought of that already. You can throw all your vertices into buckets based on their location relative to the centroid. When a bucket gets more than an arbitrary number of vertices full, you can split it. Then take the mean of the vertices in that bucket as the vertex to use in your bounding hull. Or, forget the buckets, and when you're moving around the centroid, only choose a point if its more than a given distance from the last point.
Actually, you could probably just use all the vertices in your polygon as "cloud of points" and calculate the concave hull around that. I'll look for an algorithm link. Worst case on this would be a completely convex polygon.
Another alternative is to start with a bounding rectangle. For each vertex on the rectangle, find the distance from the point to the polygon. For the farthest vertex, split it into two more vertices and move them in some. Repeat until some proportion of either vertices or area is met. I'd have to think about the details of this one a little more.
If you care about the polygon actually looking similar, even in the case of a self-intersecting polygon, then another approach would be required, but it doesn't sound like thats necessary since you asked about collision detection.
This post has some details about the convex hull part.
There's a lot of material out there. Just google for things like "mesh reduction", "mesh simplification", "mesh optimization", etc.