i would like to build a dynamic data structure that can hold a list of polygons and return a list of polygons that overlaps a specified rectangle.
i looked into bst trees (and quad trees) but these dont seem to work too well when the polygons overlap heavily.
any good ideas i should check out before i roll my own nonsense?
edit
lets assume all the polygons are normal non rotated rectangles. im willing to take the hit (point in polygon test) during point tests (i might be doing it anyway), and during a region test getting their bounding boxes is just as good. only a small percentage of them will actually not overlap the region in question.
I would look at 2-d segment delaunay graphs. Look also at Nef polygons. CGAL has a lot of set operations on polygons. Answers to this question may also be of value
Edit If your polygons are non rotated rectangles see R-Trees
Why do you write that yourself? Java offers complex intersection tests. You can convert your polygon data structures and your rectangle to Java.awt.geom.Area and then call the Area.intersect() method which does all the math for you.
It also takes care of all the rarely occurring (but still important) special cases which are really nasty to catch.
i just wrote a regular quadtree, that allowed each leaf node to hold unlimited polys, if the intersection of the bounds of the leaf and the bounds of each poly in the bucket were equivalent. otherwise leaf nodes are limited to 8 polys, before splitting.
Related
I have a collection of java.awt.Shape objects covering a two-dimensional plane with no overlap. These are from a data set of U.S. Counties, at a fairly low resolution. For an (x,y) latitude/longitude point, I want a quick way to identify the shape which county contains that point. What's an optimal way to index this?
Brute force would look like:
for (Shape eachShape : countyShapes) {
if (eachShape.contains(x, y)) {
return eachShape;
}
}
To optimize this, I can store the min/max bounds of the (possibly complex) shapes, and only call contains(x, y) on shapes whose rectangular bounds encompass a given x,y coordinate. What's the best way to build this index? A SortedMultiset would work for indexing on the x minima and maxima, but how to also include the y coordinates in the index?
For this specific implementation, doing a few seconds of up-front work to index the shapes is not a problem.
If possible you could try a bitmap with each shape in a different color. Then simply query the point and the color and lookup the shape.
This question is outside the scope of Stackoverflow but the answer is probably Binary Space Partitioning.
Roughly:
Divide the space in two either on the x coordinate or y coordinate using the mid-point of the range.
Create a list of counties on the two sides of that line (and divided by that line).
On each side of that line divide the collections again by the other dimension.
Continue recursively building a tree dividing alternately by x and y until you reach a satisfactory set of objects to examine by brute force.
The conventional algorithm actually divides the shapes lying across the boundary but that might not be necessary here.
A smart implementation might look for the most efficient line to divide on which is the one where the longest of the two lists is the smallest.
That involves more up front calculation but a more efficient and consistently performing partition.
You could use an existing GIS library like GeoTools and then all the hard work is already done.
Simply load your shapefile of counties and execute queries like
"the_geom" contains 'POINT(x y)
The quickstart tutorial will show you how to load the shapes, and the query tutorial will show you how to query them.
Having min an max values of coordinates of the bounds not guarantee that you can determine if one point is in or out in any situations. If you want achieve this by yourself you should implement some algorithm. There's a good one that is called "radial algorithm", I recommend that uses this, and it isn't so complicated to implement, there are sufficient bibliography and examples.
Hope this help.
I was looking around a lot but only found how to check collision for 2d objects.. for my current project I want to check colisions in 3d (I'm using obj models) - I could probably figure out something myself the problem is that I only know the center point of each object..
Is there a way to get the boarders of the object so I can check if it touches the boarders of another object? What would be the best way to get this information?
Edit: Some more information that might help:
I'm using lwjgl 2.8,
my objects are obj files,
I can get position, scale and the rotation of an object
EDIT: This is what I found on youtube:
https://www.youtube.com/watch?v=Iu6nAXFm2Wo&list=PLEETnX-uPtBXm1KEr_2zQ6K_0hoGH6JJ0&index=4
What you have is called a triangle soup[1]: you got vertex position (, texture and normal) information couppled with triangle information. What you can do is intersect each triangle from one mesh with another mesh. You can do this either brute-force (by testing all the other triangles each time) or build up a space partitioning data structure to speed up your intersections.
E.g. build an Octree per mesh and iterate over the leaves in one of them: for each of those leaves, test its bounding box against the leaves in the other tree and for each of those collision pairs brute-force test each triangles within either of those pairs against each other (or only test those from mesh A against those in mesh B, if you don't care about self-intersections).
There are libraries for these sorts of algorithms like OpenMesh or Bullet for example. But I only know of one port to Java: JBullet.
EDIT: If you're only interested in approximate collisions you can throw away all information about triangles and build a bounding volume out of your vertices (e.g. an axis aligned box is just the min and the max for all vertex positions, an oriented box is built similarly, but you have to find a good enough orientation first, a sphere is a bit more involved and finally you have a convex mesh, which uses the same sorts of intersection tests as a normal mesh, but is smaller than the original and convex, allowing for some optimisations of the general intersection test).
[1]: there are other kinds of 3D representations that record information about how the triangles are connected. You might imagine finding only two intersecting triangles in mesh A and mesh B and then start searching for intersecting triangles only in the neighbourhood of the initial intersection... these algorithms are much more involved, but for meshes that deform have the advantage, that you don't have to rebuild the space partitioning data structure each time as you have to do with triangle soups.
i want to find a circular object(Iris of eye, i have used Haar Cascase with viola Jones algorithm). so i found that hough circle would be the correct way to do it. can anybody explain me how to implement Hough circle in Java or any other easy implementation to find iris with Java.
Thanks,
Duda and Hart (1971) has a pretty clear explanation of the Hough transform and a worked example. It's not difficult to produce an implementation directly from that paper, so it's a good place for you to start.
ImageJ provides a Hough Circle plugin. I've been playing around with it several times in the past.
You could take a look at the source code if you want or need to modify it.
If you want to find an iris you should be straightforward about this. The part of the iris you are after is actually called a limbus. Also note that the contrast of the limbus is much lower than the one of the pupil so if image resolution permits pupil is a better target. Java is not a good option as programming language here since 1. It is slow while processing is intense; 2. Since classic Hough circle requires 3D accumulator and Java probably means using a cell phone the memory requirements will be tough.
What you can do is to use a fact that there is probably a single (or only a few) Limbuses in the image. First thing to do is to reduce the dimensionality of the problem from 3 to 2 by using oriented edges: extract horizontal and vertical edges that together represent edge orientation (they can be considered as horizontal and vertical components of edge vector). The simple idea is that the dominant intersection of edge vectors is the center of your limbus. To find the intersection you only need two oriented edges instead of three points that define a circle. Hence dimensionality reduction from 3 to 2.
You also don’t need to use a classical Hough circle transform with a huge accumulator and numerous calculations to find this intersection. A Randomized Hough will be much faster. Here is how it works (~ to RANSAC): you select a minimum number of oriented edges at random (in your case 2), find the intersection, then find all the edges that intersect at approximately the same location. These are inliers. You just iterate 10-30 times choosing a different random sample of 2 edges to settle in a set with maximum number of inliers. Hopefully, these inliers lie on the limbus. The median of inlier ray intersections will give you the center of the circle and the median distance to the inliers from the center is the radius.
In the picture below bright colors correspond to inliers and orientation is shown with little line segment. The set of original edges is shown in the middle (horizontal only). While original edges lie along an ellipse, Hough edges were transformed by an Affine transform to make those belonging to limbus to lie on a circle. Also note that edge orientations are pretty noisy.
I need to generate a Voronoi diagram around a concave (non-convex) inside polygon. I have looked for methods online, but I haven't been able to figure out how to do this. Basically, I generate the convex hull of the points, calculate the dual points and build an edge network between these points. However, when meeting the edges of the inside polygon, it has to look like the edge of the shape, just like the convex hull. So, by doing this and clipping all the edges at the borders, I should end up with a Voronoi diagram that has nice edges to the borders of the inside polygon and no cells that are on both sides of the inside polygon.
Let me give you an example:
The problem with this is that the cells cross the inside polygon edges and there is no visual relation between the cell structure and the polygon shape.
Does anybody know how to approach this problem? Is there some algorithm that already does this or gets close to what I'm trying to achieve?
Thank you so much for any kind of input!
You might be able to build a conforming Delaunay triangulation (i.e. a triangulation that includes the polygon edges as constraints) and then form the Voronoi diagram as the dual. A conforming triangulation will ensure that no edge in the triangulation intersects with a constraint edge - all constraint edges will be an edge in the triangulation.
Have a look at the Triangle package here, as a reference for this type of approach. In my experience it's a fast and robust library, although it's written in c not java.
I'm not sure I understand at this stage how the points (the Voronoi centres) are generated in your diagram. If you're actually looking to do mesh generation in a polygonal domain, then there may be other approaches to consider, although the Triangle package supports (conforming) Delaunay refinement mesh generation.
EDIT: It looks like you can also directly form the Voronoi diagram for general line segments, check out the VRONI library, here. Addressing your comment - I'm not sure that you can always expect to have a uniform Voronoi diagram that also conforms to a general polygonal boundary. I would expect that the shape of the polygonal boundary would impose a maximum dimension on the boundary Voronoi cells.
Hope this helps.
Clearly you need to generate your Voronoi diagram to the constraints of the greater polygon. Although you refer to it as a polygon, I notice that your example diagram has spline-based edges. Let's forget that for now.
What you want to do is to ensure that you start out with the containing polygon (whether generated by you or from another source) having edges of fairly equal length; a variance factor would make this look more natural. I would probably go for a variance of 10-20%.
Now that you have your containing polygon bounded by lines segments of approximately equal length, you have a basis from which to begin generating your Voronoi diagram. For each edge on your container:
Determine the edge normal (perp line jutting inward from centre of that segment).
Use the edge normal as a sliding scale on which to place a new Voronoi node centre. The distance away from the edge itself would be determined by what you want your average Voronoi cell "diameter" to be, if they were all taken as circles. In your example that looks like maybe 30 pixels (or whatever the equivalent in your world units would be). Again, you should apply a variance factor to this so that not every cell centre is placed equidistant from its source edge.
Generate the Voronoi cell for your newly placed centre.
Store your Voronoi cell source point in a list.
As you incrementally generate each point, you should begin to see that the algorithm subdivides each convex "constituent area" of your concave container in a radial fashion.
You may be wondering what the list is for. Well, obviously, you're not done yet, you've only generated a fraction of the total Voronoi tesselation you want. Once you have created these "boundary" cells of your concave space, you don't want new cells to be generated closer to the boundary than the boundary cells already are, you only want them inside that area. By maintaining a list of the boundary cell source points, you can then ensure that any further points you create are inside that area. It's a little bit like taking an internal Minkowski sum to ensure you have a buffer zone. Now you can randomise the rest of your cells in this derived concave space, to completion.
(Caveat emptor: You will have to be careful with this previous step. If any "passage" areas are too narrow, then the boundaries of this derived space will overlap, you will have a non-simple polygon, and you may find yourself placing points in the wrong places in spite of your efforts. The solution is to ensure that either your maximum placement distance from edges is never more than half of your minimum passage width... or use some other geometric means, including Minkowski summation as one possibility, to ensure you do not wind up with a degenerate derived polygon. It is quite possible that you will end with a multipolygon, i.e. fragments.)
I've not applied this method myself yet, but although there will certainly be bugs to work out, I think the general idea will get you started in the right direction.
Look for a paper called:
"Efficient computation of continuous skeletons" by Kirkpatrick, David G, written in 1979.
Here's the abstract:
An O(n lgn) algorithm is presented for the construction of skeletons
of arbitrary n-line polygonal figures. This algorithm is based on an
O(n lgn) algorithm for the construction of generalized Voronoi
diagrams (our generalization replaces point sets by sets of line
segments constrained to intersect only at end points). The generalized
Voronoi diagram algorithm employs a linear time algorithm for the
merging of two arbitrary (standard) Voronoi diagrams.
"Sets of line segments is the constrained to intersect only at end points" is the concave polygon you describe.
My question is, will the code given in http://pietschsoft.com/post/2008/07/Virtual-Earth-Polygon-Search-Is-Point-Within-Polygon.aspx work to find a point in one of areas mentioned in
below file (page 7-9):
http://www.weather.gov/directives/sym/pd01008006curr.pdf
looking forward,
A point-in-polygon algorithm usually just counts the number of times it crosses a line by "drawing" one out in any particular direction. It would then know if it's in the polygon or not by knowing how many times it crossed that line (even number it was outside, odd number it is inside). The code on that site looks like it just flips a boolean instead of adding to a counter but it's the same thing.
I must confess I have not read the PDF you linked too (too long!) but I've not come across an instance where the algorithm fails.
One tip might be to draw a rough square around the outermost extremeties of the polygon first and check whether it falls within that to avoid having to test each point).
I believe it will fail in some cases. The algorithm you linked to, which is correct for planar geometry, is incorrect for spherical geometry. Consider the rectangles which cross the 180th meridian, e.g. the rectangle labelled "M". The algorithm would consider that rectangle as covering the americas, Africa, and Europe, but not Asia or the Pacific.