How to fill a rectangular area with non-intersecting rotated rectangles? - algorithm

I try to create a scene for physical simulation. The scene consists of rectangular floes floating in a rectangular pond. Something like this:
So I need to fill a rectangular area with non-intersecting rotated rectangles with widths and heights in a specified range. I don't need to find an optimal coverage of the area. The goal is just to generate floes of different size without intersections.
And I'd like to get a solution without any dynamics, only using collision detection algorithms.

You could consider simulating a collection of boxes falling into a square bucket and saving the positions of all the boxes once they come to rest.
box2d is an open source 2D physics library that can do this for you - you might recognise it as the physics engine behind Angry Birds and umpteen-million Flash games.

There is what I would do:
Suppose the length of the rectangles are between [MaxSize MinSize]
r <- MaxSize
do{
Trying adding non-intersecting circles to the area with radius r and random center (x,y). We use circle instead of rectangle because intersection detecting for circles are easier than rectangles. e.g. if distance(x,y,x',y')<r+r' then we are good.
If adding circle failed{
r--;
if r< MinSize break;
}
}
Now you will have a plane full of on intersecting squares. There will be gaps because we were using circles as intersection detection. If this is not good enough for you, grow the squares to rectangles. You can do this by checking all points against a certain border and decide how much you can grow it.

To model solid (ie non-intersecting) objects, you could use a physics engine. As it happens I just the other day read Farseer tutorial for the absolute beginners, which includes a video depicting almost exactly your requirement. Farseer is a .NET version of box2d, which you may have heard of.

Related

Better pentagon/hexagon area ratio

In the Goldberg polyhedron used in H3 {5+,3}_{a,b} with {a,b}={2,2} or {8,2}, the pentagon area to hexagon area ratio is of about 0.66.
Do you know a way that I can modify a little the pentagon shape (and by conscequences the 5 coniguous hexagons of the 12 pentagons) in such a way that, the area ratio of any couple of tiles is better close to one?
In my application I both needs tile shapes close to a circle, and the ratio of of any couple of tiles close to one as much as possible (ie. I am penalized even by a very small amount of small tile area ratio)
Best
Jean-Eric
I don't think this is possible using H3. You cannot change the shape or coordinates of cells, at least within the library itself, as this would undermine the consistent indexing of points in the grid.
H3 aims for roughly equal-area cells, but there's still a significant amount of area distortion across the grid, particularly at coarser resolutions. See https://observablehq.com/#nrabinowitz/h3-area-variation for a visualization of area distortion at res 0-3. Even if pentagons were removed, the cell distortion between the smallest cells (the pentagon neighbors) and the largest cells (at the center of the icosahedron faces) is almost 1:2. This is a function of the projection of the planar hexagon grid onto the sphere (we use a gnomic projection for each face).
Depending on your use case, you may be able to correct for this by weighting data according to cell area. At present, you'd need to use an external library to calculate this, but we're in the process of adding area calculation directly to the library.

Filling a polygon with rectangles

I have a fairly smooth polygon, say an ellipse with bulges and dents converted to polygon straight lines. I wish to fill this polygon with as few rectangles as possible, but as many as to maintain accuracy in small corners in the polygon. The rectangles may be any size, and of any amount.
The reason for this is doing a hit test on a web page on the polygon. The only practical way is to fill it with divs and do hit tests on all the divs.
Of course there will be a minimum square size for any rectangle, lest we more than just approximate the polygon and recreate it with pixel size rectangles.
In the general case, if you want to exactly represent a digital shape with rectangles, you will need at least as many rectangles as there are pixels on the outline forming corners. If you think of a digital straight edge at 45°, that means one rectangle per pixel. This is a serious limitation. (And don't even think of non-digital shapes.)
This said, you accept to approximate the shape with a certain error, and I suggest that you first shrink the shape by a constant factor, up to you: you will overlay a grid on the shape an decide whether every tile belongs to the shape or not. Doing this, you turn your shape in a binary image with "big pixels", and the challenge is now to decompose this image in rectangles (exactly this time).
I suggest a simple greedy strategy such that you try to find a large rectangle that fits entirely, and then repeat with the parts that remain.
If you apply a morphological erosion operation with a larger and larger rectangular structuring element, you will find the largest rectangle the fits in the shape image. In theory, you should try all combinations of width and height and keep the largest area or perimeter; this is a large amount of work. I would recommend to try with growing squares first, and when you found the largest square to continue in the direction that allows it.
After you have found a large rectangle, erase it from the shape image and start again, until you completely erase it.

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.

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.

Algorithm to produce rounded edges and corners in a 3D mesh

Starting with a 3D mesh, how would you give a rounded appearance to the edges and corners between the polygons of that mesh?
Without wishing to discourage other approaches, here's how I'm currently approaching the problem:
Given the mesh for a regular polyhedron, I can give the mesh's edges a rounded appearance by scaling each polygon along its plane and connecting the edges using cylinder segments such that each cylinder is tangent to each polygon where it meets that polygon.
Here's an example involving a cube:
Here's the cube after scaling its polygons:
Here's the cube after connecting the polygons' edges using cylinders:
What I'm having trouble with is figuring out how to deal with the corners between polygons, especially in cases where more than three edges meet at each corner. I'd also like an algorithm that works for all closed polyhedra instead of just those that are regular.
I post this as an answer because I can't put images into comments.
Sattle point
Here's an image of two brothers camping:
They placed their simple tents right beside each other in the middle of a steep walley (that's one bad place for tents, but thats not the point), so one end of each tent points upwards. At the point where the four squares meet you have a sattle point. The two edges on top of each tent can be rounded normally as well as the two downward edges. But at the sattle point you have different curvature in both directions and therefore its not possible to use a sphere. This rules out Svante's solution.
Selfintersection
The following image shows some 3D polygons if viewed from the side. Its some sharp thing with a hole drilled into it from the other side. The left image shows it before, the right after rounding.
.
The mass thats get removed from the sharp edge containts the end of the drill hole.
There is someething else to see here. The drill holes sides might be very large polygons (lets say it's not a hole but a slit). Still you only get small radii at the top. you can't just scale your polygons, you have to take into account the neighboring polygon.
Convexity
You say you're only removing mass, this is only true if your geometry is convex. Look at the image you posted. But now assume that the viewer is inside the volume. The radii turn away from you and therefore add mass.
NURBS
I'm not a nurbs specialist my self. But the constraints would look something like this:
The corners of the nurbs patch must be at the same position as the corners of the scaled-down polygons. The normal vectors of the nurb surface at the corners must be equal to the normal of the polygon. This should be sufficent to gurarantee that the nurb edge will be a straight line following the polygon edge. The normals also ensure that no visible edges will result at the border between polygon and nurbs patch.
I'd just do the math myself. nurbs are just polygons. You'll have some unknown coefficients and your constraints. This gives you a system of equations (often linear) that you can solve.
Is there any upper bound on the number of faces, that meet at that corner?
You might you might employ concepts from CAGD, especially Non-Uniform Rational B-Splines (NURBS) might be of interest for you.
Your current approach - glueing some fixed geometrical primitives might be too inflexible to solve the problem. NURBS require some mathematical work to get used to, but might be more suitable for your needs.
Extrapolating your cylinder-edge approach, the corners should be spheres, resp. sphere segments, that have the same radius as the cylinders meeting there and the centre at the intersection of the cylinders' axes.
Here we have a single C++ header for generating triangulated rounded 3D boxes. The code is in C++ but also easy to transplant to other coding languages. Also it's easy to be modified for other primitives like quads.
https://github.com/nepluno/RoundCornerBox
As #Raymond suggests, I also think that the nepluno repo provides a very good implementation to solve this issue; efficient and simple.
To complete his answer, I just wrote a solution to this issue in JS, based on the BabylonJS 3D engine. This solution can be found here, and can be quite easily replaced by another 3D engine:
https://playground.babylonjs.com/#AY7B23

Resources