Given a 3D distance field that contains the distance to points in a grid (e.g. an ESDF or TSDF), I want to efficiently check whether a cube at an arbitrary orientation contains a point.
A straightforward approach is to perform raytracing to identify which cells are contained inside of the cube and check if any of those cells have 0 distance. This solution is unsatisfying because it throws away the distance information and is tightly coupled to the underlying ESDF via raytracing. It seems like we should be able to solve this problem more generally using the distance information and the resolution parameter.
One could imagine a more sophisticated approach which first checks the distance from the center of the cube to a point - if the value is large enough we know the cube is empty, or if it is small enough we know there is a point inside the cube. If the value is somewhere in between, we could recursively check the ambiguous regions. Because the distance function is discretized this algorithm should eventually terminate if the bookkeeping is done properly during the search.
Of course the devil is in the details and that is why I'm asking this question. What is the most efficient method to identify if there is a point inside the cube? If this is a classical problem, what is it called?
Related
I observed some applications create a geometric structure apparently by just having a set of touch points. Like this example:
I wonder which algorithms can possibly help me to recreate such geometric structures?
UPDATE
In 3D printing, sometimes a support structure is needed:
The need for support is due to collapse of some 3D object regions, i.e. overhangs, while printing. Support structure is supposed to connect overhangs either to print floor or to 3D object itself. The geometric structure shown in the screenshot above is actually a sample support structure.
I am not a specialist in that matter and I may be missing important issues. So here is what I would naively do.
The triangles having a external normal pointing downward will reveal the overhangs. When projected vertically and merged by common edges, they define polygonal regions of the base plane. You first have to build those projected polygons, find their intersections, and order the intersections by Z. (You might also want to consider the facing polygons to take the surface thickness into account).
Now for every intersection polygon, you draw verticals to the one just below. The projections of the verticals might be sampled from a regular grid or elsehow, to tune the density. You might also consider sampling those pillars from the basement continuously to the upper surface, possibly stopping some of them earlier.
The key ingredient in this procedure is a good polygon intersection algorithm.
If I have a set of points on a 2D plane (x, y) and I want to be able to find the place on that plane where the points are most densely clustered, what algorithm could I use and what would be an appropriate way to store those data points (e.g. some form of tree maybe?). I understand that 'most dense' could probably be calculated in different ways but I'm open to various interpretations (e.g. most points within a given radius).
I'd like to query and adjust the points that are on the plane in real-time: I'll happily take a hit on the time it takes to add and remove points as long as the lookup time is fast.
And forgive me, maybe my question is too vague. If so, I'd welcome pointers to how you can generally query a 'density map' (and whether that is the right term?).
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 have a lot of points (hundreds of thousands) and I want to check which ones are inside a polygon. For a relatively small polygon (i.e., likely to contain only tens or hundreds of points) I can just use the bounding box of the polygon as an initial check, and then do a regular point-in-poly check for those points inside the box. But imagine a large (i.e., likely to contain thousands of my points), irregularly shaped polygon. Many points will pass the bounding box check, and furthermore the point-in-poly check will be more expensive because the larger polygon is made up of many more points. So I'd like to be able to filter most points in or out without having to do the full point-in-poly check.
So, I have a plan, and mainly I want to know if what I'm describing is a well-known algorithm, and if so what it's called and where I might find existing code for it. I don't believe what I'm describing is either a quad-tree or an r-tree, and I don't know how to search for it. I'm calling it a "rect tree" below.
The idea is, to handle these larger polygons:
Do a "rect tree" pre-process, where the depth of the rect tree varies by the size of the polygon (i.e., allow more depth for a larger polygon). The rect tree would divide the bounding box of the polygon into four quarters. It would check if each quarter-rect is fully inside the polygon, fully outside the polygon, or neither. In the case of neither it would recursively divide the subrects, continuing in this way until all rects were either fully inside or outside, or the max depth had been reached. So the idea is that (a) the pre-processing time to make this tree, even though it itself will do several point-in-polygon checks, is well worth it because that time is dwarfed by the number of points to be checked, and (b) the vast majority of points can be dealt with using simple bounding box checks (generally a few such checks as you descend the tree), and then a relatively small number would have to do the full point-in-polygon check (for when you reach a leaf node that is still "neither").
What's that algorithm called? And where is the code? It doesn't in fact seem so hard to write, but I figured I'd ask before jumping into coding.
I actually ended up using a related but different approach. I realized that essentially this tree structure I was building up was no more than the polygon drawn at a low resolution. For instance, if my tree went down to a depth of 8, really that was just like drawing my polygon on a bitmap with resolution 256x256 and then doing pixel hit tests against that polygon. So I extended that idea and used a fast graphics library (the CImg library). I draw the polygon on a black-and-white bitmap of size 4000x4000. Then I just check the points as pixels against that bitmap. The magic is that drawing that huge bitmap is really fast compared to the time it was taking me to construct the tree. So I get much higher resolution than I ever could have with my tree.
One issue is being able to detect points near the very edge of the polygon, which may be included or excluded incorrectly due to rounding/resolution issues, even at the 4000x4000 size. If you need to know precisely whether those points are in or out, you could draw a stroke around the polygon in another color, and if your pixel test hit that color, you'd do the full point in poly check. For my purposes the 4000x4000 resolution was good enough (I could tolerate incorrect inclusion/exclusion for some of my edge points).
So the fundamental trick of this solution is the idea that polygon drawing algorithms are just super fast compared to other ways you might "digitize" your polygon.
Imagine we have a 2D sky (10000x10000 coordinates). Anywhere on this sky we can have an aircraft, identified by its position (x, y). Any aircraft can start moving to another coordinates (in straight line).
There is a single component that manages all this positioning and movement. When a aircraft wants to move, it send it a message in the form of (start_pos, speed, end_pos). How can I tell in the component, when one aircraft will move in the line of sight of another (each aircraft has this as a property as radius of sight) in order to notify it. Note that many aircrafts can be moving at the same time. Also, this algorithm is good to be effective sa it can handle ~1000 planes.
If there is some constraint, that is limiting your solution - it can probably be removed. The problem is not fixed.
Use a line to represent the flight path.
Convert each line to a rectangle embracing it. The width of the rectangle is determined by your definition of "close" (The bigger the safety distance is, the wider the rectangle should be).
For each new flight plan:
Check if the new rectangle intersects with another rectangle.
If so, calculate when will each plane reach the collision point. If the time difference is too small (and you should define too small according to the scenario), refuse the new flight plan.
If you want to deal with the temporal aspect (i.e. dealing with the fact that the aircraft move), then I think a potentially simplification is lifting the problem by the time dimension (adding one more dimension - hence, the original problem, being 2D, becomes a 3D problem).
Then, the problem becomes a matter of finding the point where a line intersects a (tilted) cylinder. Finding all possible intersections would then be n^2; not too sure if that is efficient enough.
See Wikipedia:Quadtree for a data structure that will make it easy to find which airplanes are close to a given airplane. It will save you from doing O(N^2) tests for closeness.
You have good answers, I'll comment only on one aspect and probably not correctly
you say that you aircrafts move in form (start_pos, speed, end_pos)
if all aircrafts have such, let's call them, flightplans then you should be able to calculate directly when and where they will be within certain distance from each other, or when will they be at closest point from each other or if the will collide/get too near
So, if they indeed move according to the flightplans and do not deviate from them your problem is deterministic - it boils down to solving a set of equations, which for ~1000 planes is not such a big task.
If you do need to solve these equations faster you can employ the techniques described in other answers
using efficient structures that can speedup calculating distances (quadtree, octree, kd-trees),
splitting the problem to solve the equations only for some relevant future timeslice
prioritize solving equations for pairs for which the distance changes most rapidly
Of course converting time to a third dimension turns the aircrafts from points into lines and you end up searching for the closest points between two 3d lines (here's some math)
I actually found an answer to this question.
It is in the book Real-Time Collision Detection, p. 223. It's better named, as well: Intersecting Moving Sphere Against Sphere, where a 2D sphere is a circle. It's not so simple (and I may also violate some rights) to explain it here, but the basic idea is to fix one of the circles as a point, adding its radius to the radius of the moving one. The new direction for the moving one is the sum of the two original vectors.