Fill polygon with smaller shapes (circles) - algorithm

I'm just going to try and explain my problem with images:
The program receives an input (image):
There is a base polygon, but can be simplified into a circle in all situations:
Output should be something like:
There is no correct result, just good and bad ones.
To make things easier, an estimate how many circles there should be can be given based on the surface and extent of the polygon.
What I am searching is an algorithm that does something described above - cover as much as possible with the given shape, while minimizing the area of black pixels and overlapping areas.

I used k-means clustering to find circle centers. Number of clusters is calculated:
numberOfClusters = round(polygonArea / basePolygonArea).
Input data for k-means algorithm are points of white pixels.

Related

Dividing the plane into regions of equal mass based on a density function

Given a "density" scalar field in the plane, how can I divide the plane into nice (low moment of inertia) regions so that each region contains a similar amount of "mass"?
That's not the best description of what my actual problem is, but it's the most concise phrasing I could think of.
I have a large map of a fictional world for use in a game. I have a pretty good idea of approximately how far one could walk in a day from any given point on this map, and this varies greatly based on the terrain etc. I would like to represent this information by dividing the map into regions, so that one day of walking could take you from any region to any of its neighboring regions. It doesn't have to be perfect, but it should be significantly better than simply dividing the map into a hexagonal grid (which is what many games do).
I had the idea that I could create a gray-scale image with the same dimensions as the map, where each pixel's color value represents how quickly one can travel through the pixel in the same place on the map. Well-maintained roads would be encoded as white pixels, and insurmountable cliffs would be encoded as black, or something like that.
My question is this: does anyone have an idea of how to use such a gray-scale image (the "density" scalar field) to generate my "grid" from the previous paragraph (regions of similar "mass")?
I've thought about using the gray-scale image as a discrete probability distribution, from which I can generate a bunch of coordinates, and then use some sort of clustering algorithm to create the regions, but a) the clustering algorithms would have to create clusters of a similar size, I think, for that idea to work, which I don't think they usually do, and b) I barely have any idea if any of that even makes sense, as I'm way out of my comfort zone here.
Sorry if this doesn't belong here, my idea has always been to solve it programatically somehow, so this seemed the most sensible place to ask.
UPDATE: Just thought I'd share the results I've gotten so far, trying out the second approach suggested by #samgak - recursively subdividing regions into boxes of similar mass, finding the center of mass of each region, and creating a voronoi diagram from those.
I'll keep tweaking, and maybe try to find a way to make it less grid-like (like in the upper right corner), but this worked way better than I expected!
Building upon #samgak's solution, if you don't want the grid-like structure, you can just add a small random perturbation to your centers. You can see below for example the difference I obtain:
without perturbation
adding some random perturbation
A couple of rough ideas:
You might be able to repurpose a color-quantization algorithm, which partitions color-space into regions with roughly the same number of pixels in them. You would have to do some kind of funny mapping where the darker the pixel in your map, the greater the number of pixels of a color corresponding to that pixel's location you create in a temporary image. Then you quantize that image into x number of colors and use their color values as co-ordinates for the centers of the regions in your map, and you could then create a voronoi diagram from these points to define your region boundaries.
Another approach (which is similar to how some color quantization algorithms work under the hood anyway) could be to recursively subdivide regions of your map into axis-aligned boxes by taking each rectangular region and choosing the optimal splitting line (x or y) and position to create 2 smaller rectangles of similar "mass". You would end up with a power of 2 count of rectangular regions, and you could get rid of the blockiness by taking the centre of mass of each rectangle (not simply the center of the bounding box) and creating a voronoi diagram from all the centre-points. This isn't guaranteed to create regions of exactly equal mass, but they should be roughly equal. The algorithm could be improved by allowing recursive splitting along lines of arbitrary orientation (or maybe a finite number of 8, 16, 32 etc possible orientations) but of course that makes it more complicated.

Algorithm for a "Blob" Border

I have several 2 dimensional circles that I want to draw a border around. I've done this using a convex hull before, but my goal is to make the border almost like a surrounding "blob". I attached a picture to show what I mean.
Essentially, I want the border to outline the circles, and be pulled slightly into the middle of the area if no circles are present. The center shape shows my current train of thought -- create normal lines for each circle, and somehow merge them into a complete shape.
Summed up, I have 2 questions:
1. Are there any existing algorithms to do this?
2. If not, are there any algorithms that would help me merge the circle outlines into a single larger path?
Thank you!
"Everything You Always Wanted to Know About Alpha Shapes But Were Afraid to Ask" is for you http://cgm.cs.mcgill.ca/~godfried/teaching/projects97/belair/alpha.html
One way to get this border could be to simply compute the distance to the centers of circles: for a given point this distance is the minimum of the distances from this point to all the centers of the given circles. Then sample this distance function over a regular grid. And finally extract the f-level of this function as a collection of polylines with an isocurve extraction algorithm (like Marching Squares). f should be the radius of the circles augmented with the desired margin.

Cover a Concave Polygon with a minimum number of rectangles

I am tyring to cover a simple concave polygon with a minimum rectangles. My rectangles can be any length, but they have maximum widths, and the polygon will never have an acute angle.
I thought about trying to decompose my concave polygon into triangles that produce a set of minimumally overlapping rectangles minimally bounding each triangle and then merging those rectangles into larger ones. However, I don't think this will work for small notches in the edges of the polygon. The triangles created by the reflex vertices on those notches will create the wrong rectangles. I am looking for rectangles that will span/ignore notches.
I don't really know anything about computational geometry, so I'm not really sure on how to begin asking the question.
I found other posts that were similar, but not what I need:
split polygon into minimum amount of rectangles and triangles
Covering an arbitrary polygon with minimum number of squares
Find $k$ rectangles so that they cover the maximum number of points
Algorithm for finding the fewest rectangles to cover a set of rectangles
Some examples: Black is the input. Red is the acceptable output.
Another exmaple: The second output is prefered. However, generating both outputs and using another factor to determine preference is probably necessary and not the responsibility of this algorithm.
Polygons that mimic curves are extremely rare. In this scenario much of the area of the rectangles is wasted. However, this is acceptable because each rectangle obeys the max width constraint.
Also, I found this article to be close to what I need:
Covering with rectangular pieces by Paul Iacob, Daniela Marinescu, and Cristina Luca
Maybe a better question is "How can I identify rectangular-like portions of a concave polygon?"
Here is an image showing the desired implementation:
The green is the actual material usage. The red rectangles are the layouts. The blue is the MBR of the entire polygon. I am thinking I should try to get little MBRs and fill them in. The 2-3 green rectangles in the upper left corner that terminate into the middle of the polygon are expensive. That is what I want to minimize. The green rectangles have a min and max width and height, but I can use as many rows and columns necessary to cover a region. Again, I must minimize the number of rectangles that do not span across the input. I can also modify the shape of the green rectangle to fit in small places that is also very expensive. In other words, getting as many rectangles as possible to span as much as possible is ideal.
Maybe I should simply be trying to identify rectangular regions like this:
Or, perhaps a better approach would be using largest-inscribed rectangles instead of MBRs. I could continually cut my polygon down using rectangles until I am left with regions were the largest-inscribed rectangle is not sharing an edge with the original polygon. The remaining regions would have to be handled with a heuristic approach.
I've been working with the engineering and manufacturing departments at my company to bring more clarificaiton to this problem. I am still waiting to confirm, but I am now thinking an algorithm that would return sets of largest inscribed rectangles would work. While it does not completely cover the shape, it would give preference to the orthognal regions while leaving the non-orthogonal regions to some heuristics. The only trick is to maxamize those orthogonal regions.

Packing Rectangles Algorithm

I need to solve the following problem:
I have multiple rectangles of sizes: width height, width/2 height/2, width/4 height/4 , width/8 height/8 ... etc
I need to pack these rectangles in a big rectangle of size x*width y*height such that no rectangles overlap, the rectangles are distributed randomly in the packing and any rectangle should at least touch another rectangle. I tried a fairly basic greedy algorithm but it fails.
Can you give me some suggestions on how to solve the problem?
Thanks!
EDIT: You can have more than one rectangle of each size
This is not homework. I'm trying to create an effect similar to the effect on ted.com
By random I mean that there might exist more than one packing of the rectangles that satisfies the constraints. The algorithm should not produce the same packing at each run.
This sounds like a rectangle packing problem. There is a link there to an algorithm. That code packs the rectangles as tightly as possible. You said you want the rectangles to be distributed randomly, which I'm guessing means not all rectangles of one size next to each other and all rectangles spread out to fill the big rectangle. Maybe the code at the link above would be a good starting point to get some ideas.
You can use a spatial index or a quadtree to subdivide the 2d-plane. The idea is to reduce the 2d problem to a 1d-problem. Once you got the spatial index (or space-filling-curve) and you can discretize the 2d into 1d you can use the 1d to search for similarity or to sort from low to high or the reverse for example by the length. If you got this order you can then compute the index back to a 2d represenation and to pack them in most efficent way in your container. There are many ways to make a spatial index. Some of the best but difficult to make is the hilbert curve. Another one is the z-curve or morton-curve. It's different from zizag-curve because it's subdivide the plane into 4 squares (not rectangles).
EDIT: Here is a link for an Jquery-Plugin: http://www.fbtools.com/jquery/treemap/
Here with world poplulation: http://www.fbtools.com/jquery/treemap/population.html
EDIT: http://people.csail.mit.edu/konak/papers/socg_2008-circular_partitions_with_applications_to_visualization_and_embeddings.html
EDIT: http://lip.sourceforge.net/ctreemap.html
At each step you divide the surface of your new rectange by 4.
SUM(1/4n for n in [0,inf]) = 4/3**
So the best you can do is fit your rectangle in a rectangle of surface
4/3 (height*width)
(that's a lower bound)
#mloskot algorithm gives a possible solution that will be in a rectangle of surface 3/2*(height*width) : Here is an illustration:
I don't see how you can do better.
Assuming you have only one rectangle of each size, you can try to replicate the arrangement of paper sizes. Sort the rectangles by size from the biggest to the smallest, then
Take first rectangle and place it at the corner of the target plane.
Take next rectangle (assert it's smaller than the previous rectangle)
Rotate about 90 degrees
Place so
its shorter size is adjacent to the longer size of the last bigger neighbour
and its longer side is adjacent to the edge of the target plane or edge of neighbour of the same
size
Repeat 2 - 4
I realise the description might be unclear, so here is picture presenting the solution - it should help to grasp it:
This is a lot like MIP-mapping

How can I fill an outline with predefined tangram shapes?

I am interested in using shapes like these:
Usually a tangram is made of 7 shapes(5 triangles, 1 square and 1 parallelogram).
What I want to do is fill a shape only with tangram shapes, so at this point,
the size and repetition of shapes shouldn't matter.
Here's something I manually tried:
I am a bit lost on how to approach this.
Assuming I have a path (an ordered list/array of points of the outline),
I imagine I should try to do some sort of triangulation.
Is there such a thing as Deulanay triangulation with triangles constrained to 45 degrees
right angled triangles ?
A more 'brute' approach would be to add a bunch of triangles(45 degrees) and use SAT
for collision detection to 'fix' overlaps, and hopefully gaps will be avoided.
Since the square and parallelogram can be made of triangles(45 degrees) too, I imagine there
would be a nice clean geometric solution, right ?
How do I pack triangles(45 degrees) inside an arbitrary shape ?
Any ideas are welcome.
A few random thoughts (maybe they help you find a better solution) if you're using only the original sizes of the shapes:
as you point out, all shapes in the tangram can be made composed of e.g. the yellow or pink triangle (d-g-c), so try also thinking of a bottom-up approach such as first trying to place as many yellow triangles into your shape and then combine them into larger shapes if possible. In the worst case, you'll end up with a set of these smallest triangles.
any kind triangulation of non-polygons (such as the half-moon in your example) probably does not work very well...
It looks like you require that the shapes can only have a few discrete orientations. To find the best fit of these triangles into the given shape, I'd propose the following approximate solution: draw a grid of triangles (i.e. a square grid with diagonal lines) across the shape and take those triangles which are fully contained. This most likely will not give you the optimal coverage but then you could repeatedly shift the grid by a tenth of the grid size in horizontal and vertical direction and see whether you'll find something which covers a larger fraction of the original shape (or you could go in steps of 1/2 then 1/4 etc. of the original grid size in the spirit of a binary search).
If you allow any arbitrary scaling of the shapes you could approximate any (reasonably smooth ?) shape to arbitrary precision by adding smaller and smaller shapes. E.g. if you have a raster image, you can e.g. choose the size of the yellow triangle such that two of them make a pixel on the image and then you can represent any such raster image.

Resources