I am not sure if this algorithm exists, much appreciated if someone can provide me the just the Algorithm's name, then I can Google it up.
Basically let's say I have N Points within a polygon (both convex and concave), and I would like to have a way/algorithm to split this polygon into N polygons, that each of these N polygon contains 1 point only.
Thanks.
I'm reluctant to post this as an answer, but it won't fit in the comments.
In the GIS world, this is sometimes referred to as voronoi algorithm. Most GIS tools, like ESRI ArcMap can generate veronoi polgons from a set of points. For your use case I think you can create a veronoi polygon set from your points using the package in the link below (it it's compatible), then take that output, and do some fancy spatial joining to replace your polygon with multiple polygons.
Here is a link to the wikipedia page describing the concept
http://en.wikipedia.org/wiki/Voronoi_diagram
also delaunoy triangulation is another approach you might want to look at
http://www.spatialdbadvisor.com/oracle_spatial_tips_tricks/283/application-of-delaunay-triangulation-and-inverse-distance-weighting-idw-in-oracle
here's another link that has the st_veronoi function mentioned with a link to the above.
http://www.spatialdbadvisor.com/source_code/223/geoprocessing-package-documentation
the basis of this package appears to be java JTS, which is apparently being compiled within java stored procs in oracle. JTS is the "standard" for geometry operations in Java. I think I'm going to give it a try myself.
Bear in mind, I have only done this using a tool like ArcGIS, not using anything i mentioned above.... so HTH and I'm not leading you down a rat hole.
I can't give you a name but can describe three different algorithms
I'm going to call the set of points you are given "targets" to simplify my solution beacuse I want to call arbitrary locations on the plain "points":
You're going to be doing quite a lot of arithmetic on 2-vectors
my algorithm to partition the polygon is simple: find the nearest target.
the set of points nearest to any target will have straight edges. the vertices will be equidistant to three (or more) of the targets (or be where the edge intersects the boundary polygon),
your algorithm might go like this:
cross the original set of targets with itself twice to produce a set of triples rejecting those that don't copntain three distinct targets.
for each set of three find the point equidistant from all three targets if that point is closer to any other target reject it.
eventually you'll have (at most) n-2 vertices, then you just need to work out how the edges join up. which you can do this by looking at which targets spawned each vertex.
now you need to add the edges which end at infinity take a cross of targets and itself
and find the halfway points between each pair of targets, any points that don't have eactly two nearest targets can be rejected, each of these ponts represents a line (perpendicular bisector) and it will end at one a vertex or at infinity
finally trim the map using the boundary polygon, you may want to drop one of the edges from any fragment that does not contain a target
another way
on the other hand you could use a fractal partitioning scheme to divide the polygon into chunks dividing each chunk smaller until it contains a single polygon, the results will be less aesthetically pleasing but looks weren't a design requirement AFAICT.
eg the fractal mapping used for IP addresses.
then having converted coordinates into numbers into divide this into chunks at convenient points, (IE by dropping unneeded trailing 1's)
another way
measure the extent of set of targets if it is wider than it is high draw a line vertically dividing it in half else draw horizontally.
if the lit hots one of the targets adjust it so that it misses.
repeat for each half until the extet is zero (which means a single point)
You didn't mention any restriction on the shapes of the containing polygons, so I'll assume you don't care. I'll also assume we're in two dimensions, though this can easily be extended. The idea is simple: create new polygons by slicing up your initial polygon with vertical strips halfway between points adjacent on the x-axis. In cases where points share an x-coordinate, split the strip containing them with vertical slices between the points on the y-axis.
Use markg's suggestions if long, thin slices don't work for you.
Related
I am searching for an algorithm which calculates, from a list of lines, the area a given point (P) is in. The lines are stored with x and y coordinates, the resulting area schould be stored as a polygon which may has holes in it.
Here two images to illustrate what I mean:
Many CAD applications use such algorithms to let the user hatch areas. I don't know how to call such a method so I don't really know what to search for.
Edit 1: To clearify what I'm looking for:
I don't need an algorithm to calculate the area of a polygon, I need an algorithm which returns the polygon which is formed by lines around P. If P is outside any possible polygon, the algorithm fails.
(I also edited the images)
Edit 2: I read the accepted answer of this possible duplicate and it seams I'm looking for a point location algorithm.
I also stumpled across this site which does exactly explains what I'm looking for and more important it led me to the open-source CGAL library which provides the functionality to do such things. Point 4.6 of the CGAL manual gives an example how to use this library to form a region from a bunch of line segments.
One way to do it is to imagine a line from P to infinity. For each polygon test each edge to see if it crosses the line. Count up how many lines cross. If its even then the point is outside the polygon, if its odd then the point is inside the polygon.
This is a fairly standard mathematical result. If you want to get a little deeper into the subject have a look at https://en.wikipedia.org/wiki/Winding_number.
I did a fairly similar things earlier this week Detecting Regions Described by Lines on HTML5 Canvas
this calculates a the polygon around a point given a set of lines. You can see a working example at the jsfiddle mentioned in the answer
the difference is that it uses infinite mathematical lines rather than line segments, but it could easily be modified for this example.
An outline algorithm
First construct two data-structures one of line-segments one of intersection-points of line-segments. In each record which two lines give each intersection, so you can flip from
one to the other. You can get this by pair-wise intersection of line-segments.
It might be easiest to cut the segments at the intersection points so each segment only have two solutions on it, one at each end. We assume we have done this.
Prune the data-structures, remove all line-segments with no intersections and only one segment - these cannot contribute.
Find possible starting lines. You could calculate the distance from each line to the point and take the smallest. You could check for intersections with a line from the point to infinity.
Walk around the polygon anti-clockwise. With you starting line find the most anti-clockwise end. At that point find the most anti-clockwise segment. Follow that and repeat. It may happen that closed loop is formed, in which case discard all the segments in the loop. Continue until you get back to the starting point.
Check if the polygon actually encloses the point. If so we are done. If not discard segments in the polygon and start again.
I have lists of points in 3d (x,y,z)
For each list I want to divide that list into to two lists, one containing points from upper part of profile and second the lower half, just like that:
My question here is how to determine which point should go to upper-part and which one should go to lower part just from having those points with their coordinates (x,y,z).
Since points can be split in 'halves' in a lot of ways, it is good to have more criteria how to split them.
In this case it seems like you are looking for a curve, that splits point cloud, which has a shape similar to that cloud. Fitting curve of type that can cover your shapes can help. Probably polynomial of second or third order are good for these shapes.
Second idea is to create something that goes through 'middle of geometry'. In 2D case you could use medial axis approach. It can be computed for point cloud by Delaunay triangulation. If points are near some plane, you can project them on the plane and use this approach.
First, create "lines" between each adjacent point. Assuming the points are given in order around the loop, this should be easy.
Then, cast a line from 0,0(upper left) to each point. If it intersects another line to get there, it's not on the upper side. If it doesn't, it is.
It's O(n^2), so I'm sure there is a better solution, but for small sets of points, it should be fine. Note that it won't work on extremely concave shapes, but will for all of those shown.
Join adjacent edges to get lines.. Taking anticlockwise angles as positive..
In the upper part of the cloud, successive lines have increasing angles..
while in the lower part the successive lines have decreasing angles..
A lil trial and error should lead you to an appropriate hueristic..
Given two 3d objects, how can I find if one fits inside the second (and find the location of the object in the container).
The object should be translated and rotated to fit the container - but not modified otherwise.
Additional complications:
The same situation - but look for the best fit solution, even if it's not a proper match (minimize the volume of the object that doesn't fit in the container)
Support for elastic objects - find the best fit while minimizing the "distortion" in the objects
This is a pretty general question - and I don't expect a complete solution.
Any pointers to relevant papers \ articles \ libraries \ tools would be useful
Here is one perhaps less than ideal method.
You could try fixing the position (in 3D space) of 1 shape. Placing the other shape on top of that shape. Then create links that connect one point in shape to a point in the other shape. Then simulate what happens when the links are pulled equally tight. Causing the point that isn't fixed to rotate and translate until it's stable.
If the fit is loose enough, you could use only 3 links (the bare minimum number of links for 3D) and try every possible combination. However, for tighter fit fits, you'll need more links, perhaps enough to place them on every point of the shape with the least number of points. Which means you'll some method to determine how to place the links, which is not trivial.
This seems like quite hard problem. Probable approach is to have some heuristic to suggest transformation and than check is it good one. If transformation moves object only slightly out of interior (e.g. on one part) than make slightly adjust to transformation and test it. If object is 'lot' out (e.g. on same/all axis on both sides) than make new heuristic guess.
Just an general idea for a heuristic. Make a rasterisation of an objects with same pixel size. It can be octree of an object volume. Make connectivity graph between pixels. Check subgraph isomorphism between graphs. If there is a subgraph than that position is for a testing.
This approach also supports 90deg rotation(s).
Some tests can be done even on graphs. If all volume neighbours of a subgraph are in larger graph, than object is in.
In general this is 'refined' boundary box approach.
Another solution is to project equal number of points on both objects and do a least squares best fit on the point sets. The point sets probably will not be ordered the same so iterating between the least squares best fit and a reordering of points so that the points on both objects are close to same order. The equation development for this is a lot of algebra but not conceptually complicated.
Consider one polygon(triangle) in the target object. For this polygon, find the equivalent polygon in the other geometry (source), ie. the length of the sides, angle between the edges, area should all be the same. If there's just one match, find the rigid transform matrix, that alters the vertices that way : X' = M*X. Since X' AND X are known for all the points on the matched polygons, this should be doable with linear algebra.
If you want a one-one mapping between the vertices of the polygon, traverse the edges of the polygons in the same order, and make a lookup table that maps each vertex one one poly to a vertex in another. If you have a half edge data structure of your 3d object that'll simplify this process a great deal.
If you find more than one matching polygon, traverse the source polygon from both the points, and keep matching their neighbouring polygons with the target polygons. Continue until one of them breaks, after which you can do the same steps as the one-match version.
There're more serious solutions that're listed here, but I think the method above will work as well.
What a juicy problem !. As is typical in computational geometry this problem
can be very complicated with a mismatched geometric abstraction. With all kinds of if-else cases etc.
But pick the right abstraction and the solution becomes trivial with few sub-cases.
Compute the Distance Transform of your shapes and VoilĂ ! Your solution is trivial.
Allow me to elaborate.
The distance map of a shape on a grid (pixels) encodes the distance of the closest point on the
shape's border to that pixel. It can be computed in both directions outwards or inwards into the shape.
In this problem, the outward distance map suffices.
Step 1: Compute the distance map of both shapes D_S1, D_S2
Step 2: Subtract the distance maps. Diff = D_S1-D_S2
Step 3: if Diff has only positive values. Then your shapes can be contained in each other(+ve => S1 bigger than S2 -ve => S2 bigger than S1)
If the Diff has both positive and negative values, the shapes intersect.
There you have it. Enjoy !
I am looking for an algorithm as follows:
Given a set of possibly overlapping rectangles (All of which are "not rotated", can be uniformly represented as (left,top,right,bottom) tuplets, etc...), it returns a minimal set of (non-rotated) non-overlapping rectangles, that occupy the same area.
It seems simple enough at first glance, but prooves to be tricky (at least to be done efficiently).
Are there some known methods for this/ideas/pointers?
Methods for not necessarily minimal, but heuristicly small, sets, are interesting as well, so are methods that produce any valid output set at all.
Something based on a line-sweep algorithm would work, I think:
Sort all of your rectangles' min and max x coordinates into an array, as "start-rectangle" and "end-rectangle" events
Step through the array, adding each new rectangle encountered (start-event) into a current set
Simultaneously, maintain a set of "non-overlapping rectangles" that will be your output set
Any time you encounter a new rectangle you can check whether it's completely contained already in the current / output set (simple comparisons of y-coordinates will suffice)
If it isn't, add a new rectangle to your output set, with y-coordinates set to the part of the new rectangle that isn't already covered.
Any time you hit a rectangle end-event, stop any rectangles in your output set that aren't covering anything anymore.
I'm not completely sure this covers everything, but I think with some tweaking it should get the job done. Or at least give you some ideas... :)
So, if I were trying to do this, the first thing I'd do is come up with a unified grid space. Find all unique x and y coordinates, and create a mapping to an index space. So if you have x values { -1, 1.5, 3.1 } then map those to { 0, 1, 2 }, and likewise for y. Then every rectangle can be exactly represented with these packed integer coordinates.
Then I'd allocate a bitvector or something that covers the entire grid, and rasterize your rectangles in the grid. The nice thing about having a grid is that it's really easy to work with, and by limiting it to unique x and y coordinates it's minimal and exact.
One way to come up with a pretty quick solution is just dump every 'pixel' of your grid.. run them back through your mapping, and you're done. If you're looking for a more optimal number of rectangles, then you've got some sort of search problem on your hands.
Let's look at 4 neighboring pixels, a little 2x2 square. When I write algorithms like these, typically I think in terms of verts, edges, and faces. So, these are the faces around a vert. If 3 of them are on and 1 is off, then you've got a concave corner. This is the only invalid case. For example, if I don't have any concave corners, I just grab the extents and dump the whole thing as a single rectangle. For each concave corner, you need to decide whether to split horizontally, vertically, or both. I think of the splitting as marking edges not to cross when finding extents. You could also do it as coloring into sets, whatever is easier for you.
The concave corners and their split directions are your search space.. you can use whatever optimization algorithm you'd like. Branch/bound might work well. I bet you could find a simple heuristic that performs well (for example, if there's another concave corner directly across from the one you're considering, always split in that direction. Otherwise, split in the shorter direction). You could just go greedy. Or you could just split every concave vert in both directions, which would generally give you fewer rectangles than outputting every 'pixel' as a rect, and would be pretty simple.
Reading over this I realize that there may be areas that are unclear. Let me know if you want me to clarify anything.
I need to evaluate if two sets of 3d points are the same (ignoring translations and rotations) by finding and comparing a proper geometric hash. I did some paper research on geometric hashing techniques, and I found a couple of algorithms, that however tend to be complicated by "vision requirements" (eg. 2d to 3d, occlusions, shadows, etc).
Moreover, I would love that, if the two geometries are slightly different, the hashes are also not very different.
Does anybody know some algorithm that fits my need, and can provide some link for further study?
Thanks
Your first thought may be trying to find the rotation that maps one object to another but this a very very complex topic... and is not actually necessary! You're not asking how to best match the two, you're just asking if they are the same or not.
Characterize your model by a list of all interpoint distances. Sort the list by that distance. Now compare the list for each object. They should be identical, since interpoint distances are not affected by translation or rotation.
Three issues:
1) What if the number of points is large, that's a large list of pairs (N*(N-1)/2). In this case you may elect to keep only the longest ones, or even better, keep the 1 or 2 longest ones for each vertex so that every part of your model has some contribution. Dropping information like this however changes the problem to be probabilistic and not deterministic.
2) This only uses vertices to define the shape, not edges. This may be fine (and in practice will be) but if you expect to have figures with identical vertices but different connecting edges. If so, test for the vertex-similarity first. If that passes, then assign a unique labeling to each vertex by using that sorted distance. The longest edge has two vertices. For each of THOSE vertices, find the vertex with the longest (remaining) edge. Label the first vertex 0 and the next vertex 1. Repeat for other vertices in order, and you'll have assigned tags which are shift and rotation independent. Now you can compare edge topologies exactly (check that for every edge in object 1 between two vertices, there's a corresponding edge between the same two vertices in object 2) Note: this starts getting really complex if you have multiple identical interpoint distances and therefore you need tiebreaker comparisons to make the assignments stable and unique.
3) There's a possibility that two figures have identical edge length populations but they aren't identical.. this is true when one object is the mirror image of the other. This is quite annoying to detect! One way to do it is to use four non-coplanar points (perhaps the ones labeled 0 to 3 from the previous step) and compare the "handedness" of the coordinate system they define. If the handedness doesn't match, the objects are mirror images.
Note the list-of-distances gives you easy rejection of non-identical objects. It also allows you to add "fuzzy" acceptance by allowing a certain amount of error in the orderings. Perhaps taking the root-mean-squared difference between the two lists as a "similarity measure" would work well.
Edit: Looks like your problem is a point cloud with no edges. Then the annoying problem of edge correspondence (#2) doesn't even apply and can be ignored! You still have to be careful of the mirror-image problem #3 though.
There a bunch of SIGGRAPH publications which may prove helpful to you.
e.g. "Global Non-Rigid Alignment of 3-D Scans" by Brown and Rusinkiewicz:
http://portal.acm.org/citation.cfm?id=1276404
A general search that can get you started:
http://scholar.google.com/scholar?q=siggraph+point+cloud+registration
spin images are one way to go about it.
Seems like a numerical optimisation problem to me. You want to find the parameters of the transform which transforms one set of points to as close as possible by the other. Define some sort of residual or "energy" which is minimised when the points are coincident, and chuck it at some least-squares optimiser or similar. If it manages to optimise the score to zero (or as near as can be expected given floating point error) then the points are the same.
Googling
least squares rotation translation
turns up quite a few papers building on this technique (e.g "Least-Squares Estimation of Transformation Parameters Between Two Point Patterns").
Update following comment below: If a one-to-one correspondence between the points isn't known (as assumed by the paper above), then you just need to make sure the score being minimised is independent of point ordering. For example, if you treat the points as small masses (finite radius spheres to avoid zero-distance blowup) and set out to minimise the total gravitational energy of the system by optimising the translation & rotation parameters, that should work.
If you want to estimate the rigid
transform between two similar
point clouds you can use the
well-established
Iterative Closest Point method. This method starts with a rough
estimate of the transformation and
then iteratively optimizes for the
transformation, by computing nearest
neighbors and minimizing an
associated cost function. It can be
efficiently implemented (even
realtime) and there are available
implementations available for
matlab, c++... This method has been
extended and has several variants,
including estimating non-rigid
deformations, if you are interested
in extensions you should look at
Computer graphics papers solving
scan registration problem, where
your problem is a crucial step. For
a starting point see the Wikipedia
page on Iterative Closest Point
which has several good external
links. Just a teaser image from a matlab implementation which was designed to match to point clouds:
(source: mathworks.com)
After aligning you could the final
error measure to say how similar the
two point clouds are, but this is
very much an adhoc solution, there
should be better one.
Using shape descriptors one can
compute fingerprints of shapes which
are often invariant under
translations/rotations. In most cases they are defined for meshes, and not point clouds, nevertheless there is a multitude of shape descriptors, so depending on your input and requirements you might find something useful. For this, you would want to look into the field of shape analysis, and probably this 2004 SIGGRAPH course presentation can give a feel of what people do to compute shape descriptors.
This is how I would do it:
Position the sets at the center of mass
Compute the inertia tensor. This gives you three coordinate axes. Rotate to them. [*]
Write down the list of points in a given order (for example, top to bottom, left to right) with your required precision.
Apply any algorithm you'd like for a resulting array.
To compare two sets, unless you need to store the hash results in advance, just apply your favorite comparison algorithm to the sets of points of step 3. This could be, for example, computing a distance between two sets.
I'm not sure if I can recommend you the algorithm for the step 4 since it appears that your requirements are contradictory. Anything called hashing usually has the property that a small change in input results in very different output. Anyway, now I've reduced the problem to an array of numbers, so you should be able to figure things out.
[*] If two or three of your axis coincide select coordinates by some other means, e.g. as the longest distance. But this is extremely rare for random points.
Maybe you should also read up on the RANSAC algorithm. It's commonly used for stitching together panorama images, which seems to be a bit similar to your problem, only in 2 dimensions. Just google for RANSAC, panorama and/or stitching to get a starting point.