To get right to it: Say I've got two specific pixels a & b, as well as a list of random others. I now want to check all pixels in that list if they are on the line which passes through a & b (but which is NOT restricted to have a & b as endpoints!)
I looked at Bresenham's line algorithm, but that seems to only find the points between a & b?
I've also had a look at linear equations in general but I'm kind of stuck on how to properly discretize the continuous line into pixels...
(I'm trying to implement a random sampling algorithm in java, which tries to find the line with the most pixels on it, if that matters).
Thanks a lot for any help with this :)
I strongly suggest that you compute the distance between the point and the line.
If you use one pixel as unit of measurement (which you will if you work in a pixel coordinate system), you can simply check if the distance from the point to the line is < 1.
Here's how to compute the distance between a point and a line:
Minimum Distance between a Point and a Line
Wolfram: Point-Line Distance--2-Dimensional
You could search not between a and b, but between the points that are on the same line, but out of the borders of image. You can get them simply putting vector (b-a) necessary amount of times to the a side and to the b side. And the use your Bresenham's line algorithm.
As for more concrete answers, define the question better, please. Do you consider pixels as points or squares or circles? What is "pixel is on the line" in your terms? What width has your line? You are looking for the line with max number of pixels on the cm length or in the rectangle borders? Among what lines do you search?
Related
In my application I work with OpenGL and large arrays of data.
One of the things I need to do is I receive multiple "simple" polygons that can be either convex or concave. By simply I mean geometrical definition - polygons without holes and intersecting edges.
I receive this poligons in the form of linked loop of points (vertices), where each Vi is connected to Vi-1 and Vi+1 points and nothing else. The last point is also connected to the first, giving us a loop as a result.
I will say right now that I figured out polygon triangulation, and it works like a charm (I used ear-clipping method for now).
But, I need to build LOTS of those polygons, millions of them. To minimize the load I decided to split my world into "chunks", squares like in Minecraft. I then use frustum culling and other optimizations methods to either render or discard/simplify these chunks and meshes in them.
So, what I want to do is: if the polygon I received lies in several different chunks - then I want to split it into meshes for each of those chunks. Basically, I want to create multiple polygons that are divided on chunk borders, and THEN triangulate them and create meshes for rendering.
As a result I want to have one (or several) contours that I can then triangulate.
here's a picture of my task:
I made an algorythm for splitting it myself that I thought would work, but I found that it only works if the contour in any given chunk doesn't break up, like you see in the example (in other words if there's only one figure in any given chunk).
I thought to ask here if anyone knows any good algorythms for that task? I'll probably come up with something myself, but practice shows that there's almost always a better and simpler ready-made solution out there. I'd really appreciated it if someone could give me a useful link or an article, if not with a solution itself, then something that could give ideas.
I'm not at work at the moment, because it's weekend, so I'll be trying/testing the things on Monday.
What I came up with at the moment, however, is a very simple solution.
test all points in the contour.
If point i and point i+1 don't belong to the same chunk (which I can test easily):
then find an intersection between chunk border and the line made by these two points.
add this new point to the contour between the original two points.
When every edge of the polygon was tested like that - triangulate it.
because we have points on the edges of the chunks - then during triangulation the triangles will fit exactly into chunk borders
for each triangle, decide which chunk it belongs to and generate the mesh in THAT chunk.
I won't go into details of some optimization ideas - like not needing to evaluate resulting triangles if the entire figure fits within the same chunk.
This is a stab in the dark at writing some pseudo code that may work. Feel free to implement it and select your own answer with the actual code if it works.
First, convert your vertex array to a double linked list that loops from the last element to the first element. Or it may be better to model it as an undirected graph instead, because a point may have missing neighbours.
Then apply the algorithm below for each quadrant, starting with the full polygon each time. You can cut down the size of that polygon by culling vertices that are outside of the quadrant and at least 1-neighbour away from edges that cross the cutting lines.
// We need to keep track of the points that we insert on the cutting lines
let LIX = List of X-Cut-Line Intersection Points
let LIY = List of Y-Cut-Line Intersection Points
foreach Edge AB in Poly where A is inside the quadrant, B outside
// Insert points into the polygon that intersect the X-Cut-Line
if AB Intersects X-Cut-Line
let Ix = Intersection Point
Insert Ix between AB so that A<->B becomes A<->Ix
B can be removed from the polygon now
Add Ix to LIX
// Insert points into the polygon that intersect the Y-Cut-Line
if AB.Intersects Y-Cut-Line
let Iy = Intersection Point
Insert Iy between AB so that A<->B becomes A<->Iy
B can be removed from the polygon now
Add Iy to LIY
// Then iterate pairs of points along each cutting line to join them
sort LIX by X Ascending
while (LIX.Length > 0)
let P0 = LIX[0]
let P1 = LIX[1]
Link P0 and P1
Remove P0 and P1 from LIX
sort LIY by Y Ascending
while (LIY.Length > 0)
let P0 = LIY[0]
let P1 = LIY[1]
Link P0 and P1
Remove P0 and P1 from LIY
Finally, you can look for cycles in the resulting linked list/graph to find the new polygons. Each cycle should in theory not contain points from the other cycles already detected so it is an individual polygon.
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 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.
I have an image such as this:
and I need to calculate the orientation of it. In this case the shape is pointing towards the top left of the screen. Accuracy isn't hugely important as long as 3 or 4 calculations average out to within 5 degrees or so of the actual orientation (it will be moving slightly).
Can anyone point me towards an algorithm to do this? I don't mind if the orientation is returned as a double or as a vector.
If the image is always T-shaped, you can simply get the furthest pair of pixels, then find the furthest pair from either both of those (the edges of the T), find which is further from the other two, draw a line from that one to the middle point of those two.
You can further refine it by then finding the base of the T by comparing the middle line with the edges of the base, and adjusting the angle and offset until it is actually in the middle.
The definitive solution is impossible I guess, since requires image recognition. I would project the 2D image onto axis, i.e. obtain the width and height of the image and get direction vector from these values taking them as components.
First, a couple of assumptions:
The center and centroid are "close"
The descending bar of the T is longer than the cross-bar
First, determine the bounding rectangle of the image and find the points of the image that lie along this rectangle. For points that lie along the line and are a certain distance from one another (say 5 pixels to pick a value) you'll need to only take 1 point from that cluster. At the end of this you should have 3 points, i.e. a triangle. The shortest side of the triangle should be the cross-bar (from assumption 2), i.e. find the two points closest to each other. The line that is perpendicular to the line crossing those two points is then your orientation line, i.e. find the angle between it and the horizontal axis.
I would try morphological skeletonization to simplify the image, followed by some straightforward algorithm to determine the orientation of the longer leg of the skeleton.
The solution in the end was to use a Convex Hull Algorithm, which finds the minimum number of points needed to enclose a shape with a bound.
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.