I have an array with the coordinates of the center of small circles which have the same radius. I know how to find when the mouse is over a circle, but my array is big and I want the fastest way to calculate this operation.
Is there a way of finding if the mouse is over a circle without looping all the array for each movement of the mouse?
Initially, set up some 'zones' for quicker reference:
Separate the whole surface into a small number of rectangles that don't intersect.
For each of these rectangles, list all circles that are at least partially contained in it. (A circle may end up listed in multiple rectangles, but that's okay.)
Every time you want to check whether the mouse is over a circle, you won't have to go through the whole array of circles. Instead:
Figure out which rectangle you're in.
Check only the circles that are listed under that rectangle.
This looks like a problem of optimizing the boundary check for a large number of items. The approach of going linearly does not scale well for thousands of circles.
This is a good topic to read on the net. But first, without going there, I'll try to explain (as an exercise) what I would explore. I would create a binary tree and partition the space, then instead of using an array I would put the circle points in such a tree. Looking the tree elements that are closer to the actual X,Y location becomes a matter of doing a binary search on the tree. The you have the closest point as a result of that search and can check for collision on it. There is still more to be done to the algorithm, and further optimizations are needed. For example, how to check for more points and not only the final one? Potentially I need a tree for the X coordinate, and another for the Y coordinate, etc... But I would explore these ideas. I will come back to this post and expand my reply with an actual example and a more concrete solution.
What if you check the coordinates that are r(radius) distance from the mouse? Then you could narrow your search down in the array if it is ordered.
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'm current working on a pet project that allows a user to create a graph (vertices/edges) on screen in Java. I have the vertices implemented as JComponents but I have the edges implemented as Line2D's. When a user is moving the mouse across the canvas, if it is within a certain threshold of proximity to one of the edges (or Line2D's) that edge (the closest to the mouse) is highlighted.
My question deals with the way I implement which edge is closest to the mouse. Right now I have a mouselistener that detects movement; every time the mouse is moved my program cycles through all the lines (edges) and determines the closest one using Line2D's ptDistSeg() function. If this is within the threshold, then it is highlighted (using a thicker stroke in the paintcomponent).
To me this seems very inefficient as it has to recalculate all edge distances from the mouse every time it is moved. For the vertices this isn't a problem as the mouselisteners are associated with each vertex and therefore the vertices know when they need to handle the event. Unfortunately I can't do this with the edges as they are represented as Line2D's which can't implement a mouseListener.
So is there a more efficient way to find the closest edge or should I implement the edges a different way?
Thanks.
There's probably a better data structure for this out there somewhere, but one option would be to compute the axis-aligned bounding box of each edge to get one rectangle per edge, then to store all of these rectangles in a spatial data structure like an R-tree. R-trees support efficient queries of the form "give me all rectangles overlapping some point," so you could use that to filter down all the line segments to just those that might potentially hit the mouse point, then just test those.
The drawbacks here are that moving nodes around will require a lot of R-tree rebuilding due to the cost of changing the bounding boxes and that you'd need to find a good R-tree library, since R-trees aren't very easy to implement from scratch.
Hope this helps!
Say you have a collection of points with coordinates on a Cartesian coordinate system.
You want to plot another point, and you know its coordinates in the same Cartesian coordinate system.
However, the plot you're drawing on is distorted from the original. Imagine taking the original plane, printing it on a rubber sheet, and stretching it in some places and pinching it in others, in an asymmetrical way (no overlapping or anything complex).
(source)
You know the stretched and unstretched coordinates of each of your set of points, but not the underlying stretch function. You know the unstretched coordinates of a new point.
How can you estimate where to plot the new point in the stretched coordinates based on the stretched positions of nearby points? It doesn't need to be exact, since you can't determine the actual stretch function from a set of remapped points unless you have more information.
other possible keywords: warped distorted grid mesh plane coordinate unwarp
Ok, so this sounds like image warping. This is what you should do:
Create a Delaunay triangulation of your unwarped grid and use your knowledge of the correspondences between the warped and unwarped grid to create the triangulation for the warped grid. Now you know the corresponding triangles in each image and since there is no overlapping, you should be able to perform the next step without much difficulty.
Now, to find the corresponding point A, in the warped image:
Find the triangle A lies in and use the transformation between the triangle in the unwarped grid and the warped grid to figure out the new position.
This is explained explicitly in detail here.
Another (much more complicated) method is the Thin Plate Spline (which is also explained in the slides above).
I understood that you have one-to-one correspondence between the wrapped and unwrapped grid points. And I assume that the deformation is not so extreme that you might have intersecting grid lines (like the image you show).
The strategy is exactly what Jacob suggests: Triangulate the two grids such that there is a one-to-one correspondence between triangles, locate the point to be mapped in the triangulation and then use barycentric coordinates in the corresponding triangle to compute the new point location.
Preprocess
Generate the Delaunay triangulation of the points of the wrapped grid, let's call it WT.
For every triangle in WT add a triangle between the corresponding vertices in the unwrapped grid. This gives a triangulation UWT of the unwrapped points.
Map a point p into the wrapped grid
Find the triangle T(p1,p2,p3) in the UWT which contains p.
Compute the barycentric coordinates (b1,b2,b3) of p in T(p1,p2,p3)
Let Tw(q1,q2,q3) be the triangle in WT corresponding to T(p1,p2,p3). The new position is b1 * q1 + b2 * q2 + b3 * q3.
Remarks
This gives a deformation function as a linear spline. For smoother behavior one could use the same triangulation but do higher order approximation which would lead to a bit more complicated computation instead of the barycentric coordinates.
The other answers are great. The only thing I'd add is that you might want to take a look at Free form deformation as a way of describing the deformations.
If that's useful, then it's quite possible to fit a deformation grid/lattice to your known pairs, and then you have a very fast method of deforming future points.
A lot depends on how many existing points you have. If you have only one, there's not really much you can do with it -- you can offset the second point by the same amount in the same direction, but you don't have enough data to really do any better than that.
If you have a fair number of existing points, you can do a surface fit through those points, and use that to approximate the proper position of the new point. Given N points, you can always get a perfect fit using an order N polynomial, but you rarely want to do that -- instead, you usually guess that the stretch function is a fairly low-order function (e.g. quadratic or cubic) and fit a surface to the points on that basis. You then place your new point based on the function for your fitted surface.
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 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.