Calculating where to place one arbitrary 2d shape in another? - algorithm

How do I calculate how to fit shape A into shape B? Are there some algorithms I could look up? Neither shape should scale.
This is pretty close except he doesn't specify what routines he's using:
Find maximum area polygon inscribed in larger polygon
The actual use case is fitting a building footprint into an arbitrary area. It's for RTS AI where they need to find a location to place a building.

Related

Algorithm to optimally fit a sphere between other spheres in a 3D bounding box?

I'm struggling with a 3D problem for which I'm trying to find an efficient algorithm.
I have a bounding box with given width, height, and depth.
I also have a list of spheres. That is, a center coordinate (xi,yi,zi) and radius ri for each sphere.
The spheres are guaranteed to fit within the bounding box, and to not overlap eachother.
So my situation is like this:
Now I have a new sphere with radius r, which I have to fit inside the bounding box, not overlapping any of the previous spheres.
I also have a target point T = (x,y,z) and my goal is to fit this new sphere (given the conditions above) as close as possible to this target point.
I'm trying to construct an efficient algorithm to find an optimal position for the new sphere. Optimal as in: as close to the target point as possible. Or a "false" result if there is no space to fit this new sphere between or around the existing ones anywhere within the bounding box.
I have thought of all sorts of complex approaches, such as building some sort of parametric description of the remaining volume, starting with the bounding box and subtracting the existing spheres one by one. But it doesn't seem to lead me towards a workable solution.
Note that there are a lot of known 'sphere packing' algorithms, but they tend to just fill volumes with random spheres. Also they often use a trial and error approach, just doing a certain amount of random attempts and then terminate.
Whereas I have a given specific new sphere size, and I need to fit that in (or find out that it's not possible).
A possible approach is by computing the "distance map" of the spheres, i.e. the function that returns for every point (x, y, z) the distance to the closest sphere, which is also the distance to the closest center minus the radius of the corresponding sphere. The map is made of the intersection of (hyper)conical surfaces.
Then you can explore the distance map around the target point and find the closest point with a value that exceeds the target radius.
If I am right, the distance map is directly related to the additively weighted Voronoi diagram of the sphere centers (https://en.wikipedia.org/wiki/Weighted_Voronoi_diagram), and the vertices of the diagram correspond to local maxima. Hence the closest Voronoi vertex with a value that exceeds the target radius will give a solution.
Unfortunately, the construction of this diagram won't be a barrel of laughs. Check the article "Euclidean Voronoi diagram of 3D balls and its computation
via tracing edges" and its bibliography.
A possibly workable solution to estimate the distance map is by discretizing space in a regular grid of cubes, and for every cube obtain a lower and an upper bound of the distance function.
For a single given sphere and a given cube, it is possible to find the minimum and maximum value analytically. Then considering all spheres, you can find the smallest maximum and smallest minimum, which are an upper and lower bound of the true distance (the largest minimum won't do). Then you keep all the spheres such that the minimum remains below that upper bound and you get a (hopefully short) list of candidates.
Here you can check the distances to the spheres in the list, and if the upper bound is smaller than the target radius, you can drop the cube. If you find an upper bound above the target radius, you have found a solution.
Otherwise, if the uncertainty range on the distance function is too large, subdivide the cube in smaller ones for a more accurate estimate of the upper and lower bounds.
To obtain a solution close to the target point, you will visit the cubes by increasing distance from the target (using nested digital spheres), until you find a match.
A key point in this process is to quickly find the spheres closest to a given cube, for the initial estimates. A data structure such as a kD-tree or similar might be helpful.

Interpolating missing contour lines between existing contour lines

Contour lines (aka isolines) are curves that trace constant values across a 2D scalar field. For example, in a geographical map you might have contour lines to illustrate the elevation of the terrain by showing where the elevation is constant. In this case, let's store contour lines as lists of points on the map.
Suppose you have map that has several contour lines at known elevations, and otherwise you know nothing about the elevations of the map. What algorithm would you use to fill in additional contour lines to approximate the unknown elevations of the map, assuming the landscape is continuous and doesn't do anything surprising?
It is easy to find advise about interpolating the elevation of an individual point using contour lines. There are also algorithms like Marching Squares for turning point elevations into contour lines, but none of these exactly capture this use case. We don't need the elevation of any particular point; we just want the contour lines. Certainly we could solve this problem by filling an array with estimated elevations and then using Marching Squares to estimate the contour lines based on the array, but the two steps of that process seem unnecessarily expensive and likely to introduce artifacts. Surely there is a better way.
IMO, about all methods will amount to somehow reconstructing the 3D surface by interpolation, even if implicitly.
You may try by flattening the curves (turning them to polylines) and triangulating the resulting polygons thay they will define. (There will be a step of closing the curves that end on the border of the domain.)
By intersection of the triangles with a new level (unsing linear interpolation along the sides), you will obtain new polylines corresponding to new isocurves. Notice that the intersections with the old levels recreates the old polylines, which is sound.
You may apply a post-smoothing to the curves, but you will have no guarantee to retrieve the original old curves and cannot prevent close surves to cross each other.
Beware that increasing the density of points along the curves will give you a false feeling of accuracy, as the error due to the spacing of the isolines will remain (indeed the reconstructed surface will be cone-like, with one of the curvatures being null; the surface inside the bottommost and topmost lines will be flat).
Alternatively to using flat triangles, one may think of a scheme where you compute a gradient vector at every vertex (f.i. from a least square fit of a plane on the vertex and its neighbors), and use this information to generate a bivariate polynomial surface in the triangle. You must do this in such a way that the values along a side will coincide for the two triangles that share it. (Unfortunately, I have no formula to give you.)
The isolines are then obtained by a further subdivision of the triangle in smaller triangles, with a flat approximation.
Actually, this is not very different from getting sample points, (Delaunay) triangulating them and fitting picewise continuous patches to the triangles.
Whatever method you will use, be it 2D or 3D, it is useful to reason on what happens if you sweep the range of z values in a continous way. This thought experiment does reconstruct a 3D surface, which will possess continuity and smoothness properties.
A possible improvement over the crude "flat triangulation" model could be to extend every triangle side between to iso-polylines with sides leading to the next iso-polylines. This way, higher order interpolation (cubic) can be achieved, giving a smoother reconstruction.
Anyway, you can be sure that this will introduce discontinuities or other types of artifacts.
A mixed method:
flatten the isolines to polylines;
triangulate the poygons formed by the polylines and the borders;
on every node, estimate the surface gradient (least-square fit of a plane to the node and its neighborrs);
in every triangle, consider the two sides along which you need to interpolate and compute the derivative at endpoints (from the known gradients and the side directions);
use Hermite interpolation along these sides and solve for the desired iso-levels;
join the points obtained on both sides.
This method should be a good tradeoff between complexity and smoothness. It does reconstruct a continuous surface (except maybe for the remark below).
Note that is some cases, yo will obtain three solutions of the cubic. If there are three on each side, join them in order. Otherwise, make a decision on which to join and use the remaining two to close the curve.

Looking for an efficient algorithm to find the boundary of a swept 2d shape

I have piecewise curve defining a generator (think brush) and a piecewise curve representing the path the brush follows. I wish to generate the boundary that the generator curve creates as it is swept across the path.
This is for an engineering CAD like application. I am looking for a general algorithm or code samples in any language.
I suggest the following papers:
"Approximate General Sweep Boundary of a 2D Curved Object" by Jae-Woo Ahn, Myung-Soo Kim and Soon-Bum Lim
"Real Time Fitting of Pressure Brushstrokes" by Thierry Pudet
"The Brush-Trajectory Approach to Figure Specification: Some Algebraic-Solutions"
The actual answer we used is too complex to post in full but in summary.
Sample the curve at regular intervals along the transformed path
Build a triangular mesh by joining the vertices from each sample to
the next and previous sample
Identify candidate silhouette edge by whose neighboring triangles normals point in opposite directions
Split all edges at intersections using a sweepline algorithm. This is the tricky part as we found we had to do this with a BigRational algorithm or subtle numerical errors crept in which broke the topology.
Convert the split edges into a planar graph
Find the closest of the split edges to some external test point
Walk around the outside of the graph. ( again all tests are done using big rational )
The performance of the algorithm is not brilliant due to the BigRational calculations. However we tried many ways to do this in floating point and we always got numerical edges cases where the resulting graph was not planar. If the graph is not planar then you can't walk around the outside of it.
If your have an arbitrarily complex shape translating and rotating along an arbitrary path, figuring out the area swept (and its boundary) using an exact method is going to be a really tough problem.
You might consider instead using a rendering-based approach:
start with a black canvas
densely sample the path of your moving shape
for each sample position and rotation, render the shape as white
you now have a canvas with a fairly good estimate of the swept shape
You can follow this up with these steps:
(optional) do some image processing to try to fix up any artifacts introduced by too-sparsely sampling the path of the shape
(optional) pass the canvas through an edge-finding filter to get the boundary of the swept shape

How to fill polygon with points regularly?

It is simple to fill rectangle: simply make some grid. But if polygon is unconditioned the task becomes not so trivial.
Probably "regularly" can be formulated as distance between each other point would be: R ± alpha. But I'm not sure about this.
Maybe there is some known algorithm to achieve this.
Added:
I need to generate net, where no large holes, and no big gathering of the points.
Have you though about using a force-directed layout of the points?
Scatter a number of points randomly over the bounding box of your polygon, then repeatedly apply two simple rules to adjust their location:
If a point is outside of the polygon, move it the minimum possible distance so that it lies within, i.e.: to the closest point on the polygon edge.
Points repel each other with a force inversely proportional to the distance between them, i.e.: for every point, consider every other point and compute a repulsion vector that will move the two points directly apart. The vector should be large for proximate points and small for distant points. Sum the vectors and add to the point's position.
After a number of iterations the points should settle into a steady state with an even distribution over the polygon area. How quickly this state is achieved depends on the geometry of the polygon and how you've scaled the repulsive forces between the points.
You can compute a Constrained Delaunay triangulation of the polygon and use a Delaunay refinement algorithm (search with this keyword).
I have recently implemented refinement
in the Fade2D library, http://www.geom.at/fade2d/html/. It takes an
arbitrary polygon without selfintersections as well as an upper bound on the radius of the circumcircle of each resulting triangle. This feature is not contained in the current release 1.02 yet, but I can compile the current development version for Linux or Win64 if you want to try that.

Packing arbitrary polygons within an arbitrary boundary

I was wondering if anybody could point me to the best algorithm/heuristic which will fit my particular polygon packing problem. I am given a single polygon as a boundary (convex or concave may also contain holes) and a single "fill" polygon (may also be convex or concave, does not contain holes) and I need to fill the boundary polygon with a specified number of fill polygons. (I'm working in 2D).
Many of the polygon packing heuristics I've found assume that the boundary and/or filling polygons will be rectangular and also that the filling polygons will be of different sizes. In my case, the filling polygons may be non-rectangular, but all will be exactly the same.
Maybe this is a particular type of packing problem? If somebody has a definition for this type of polygon packing I'll gladly google away, but so far I've not found anything which is similar enough to be of great use.
Thanks.
The question you ask is very hard. To put this in perspective, the (much) simpler case where you're packing the interior of your bounded polygon with non-overlapping disks is already hard, and disks are the simplest possible "packing shape" (with any other shape you have to consider orientation as well as size and center location).
In fact, I think it's an open problem in computational geometry to determine for an arbitrary integer N and arbitrary bounded polygonal region (in the Euclidean plane), what is the "optimal" (in the sense of covering the greatest percentage of the polygon interior) packing of N inscribed non-overlapping disks, where you are free to choose the radius and center location of each disk. I'm sure the "best" answer is known for certain special polygonal shapes (like rectangles, circles, and triangles), but for arbitrary shapes your best "heuristic" is probably:
Start your shape counter at N.
Add the largest "packing shape" you can fit completely inside the polygonal boundary without overlapping any other packing shapes.
Decrement your shape counter.
If your shape counter is > 0, go to step 2.
I say "probably" because "largest first" isn't always the best way to pack things into a confined space. You can dig into that particular flavor of craziness by reading about the bin packing problem and knapsack problem.
EDIT: Step 2 by itself is hard. A reasonable strategy would be to pick an arbitrary point on the interior of the polygon as the center and "inflate" the disk until it touches either the boundary or another disk (or both), and then "slide" the disk while continuing to inflate it so that it remains inside the boundary without overlapping any other disks until it is "trapped" - with at least 2 points of contact with the boundary and/or other disks. But it isn't easy to formalize this "sliding process". And even if you get the sliding process right, this strategy doesn't guarantee that you'll find the biggest "inscribable disk" - your "locally maximal" disk could be trapped in a "lobe" of the interior which is connected by a narrow "neck" of free space to a larger "lobe" where a larger disk would fit.
Thanks for the replies, my requirements were such that I was able to further simplify the problem by not having to deal with orientation and I then even further simplified by only really worrying about the bounding box of the fill element. With these two simplifications the problem became much easier and I used a stripe like filling algorithm in conjunction with a spatial hash grid (since there were existing elements I was not allowed to fill over).
With this approach I simply divided the fill area into stripes and created a spatial hash grid to register existing elements within the fill area. I created a second spatial hash grid to register the fill area (since my stripes were not guaranteed to be within the bounding area, this made checking if my fill element was in the fill area a little faster since I could just query the grid and if all grids where my fill element were to be placed, were full, I knew the fill element was inside the fill area). After that, I iterated over each stripe and placed a fill element where the hash grids would allow. This is certainly not an optimal solution, but it ended up being all that was required for my particular situation and pretty fast as well. I found the required information about creating a spatial hash grid from here. I got the idea for filling by stripes from this article.
This type of problem is very complex to solve geometrically.
If you can accept a good solution instead of the 100% optimal
solution then you can to solve it with a raster algorithm.
You draw (rasterize) the boundary polygon into one in-memory
image and the fill polygon into another in-memory image.
You can then more easily search for a place where the fill polygon will
fit in the boundary polygon by overlaying the two images with
various (X, Y) offsets for the fill polygon and checking
the pixel values.
When you find a place that the fill polygon fits,
you clear the pixels in the boundary polygon and repeat
until there are no more places where the fill polygon fits.
The keywords to google search for are: rasterization, overlay, algorithm
If your fill polygon is the shape of a jigsaw piece, many algorithms will miss the interlocking alignment. (I don't know what to suggest in that case)
One approach to the general problem that works well when the boundary is much larger than
the fill pieces is to tile an infinite plane with the pieces in the best way you can, and then look for the optimum alignment of the boundary on this plane.

Resources