I have a following problem. A large rectangle contains smaller non-intersecting rectangles (The black rectangles in the picture below) and I need to find an algorithm to fill remaining free area with non-intersecting rectangles(red ones in the picture below). Speed is not an issue for the algorithm. Also if someone would have an example source code of the algorithm I would really appreciate that.
Edit. Small clarification I need to get the coordinates of the red rectangles not to draw them. I am also working with point data not images.
http://koti.mbnet.fi/niempi2/Squares.gif
Like most bin-packing problems this one looks like an NP-hard problem to me. With 2 rectangles, there are 8! (= 40320) possible arrangements you need to consider. Three rectangles produces 12! possibilities, a cool 480 million.
You'll need an heuristic to make this computable. Beyond favoring the outer edges of the rectangles closest to the bounding rectangle, I don't see a good one. You'd need tighter requirements on the resulting rectangles you accept, the number of them isn't going to help. Glad this is not my problem :)
Although there are multiple possible solutions, I think you can get to one fairly easily.
I would work in increasing values along one axis. By scanning all rectangles and ordering their edge's appearances along that axis, you could walk through them and create rectangles as you go. Each time you hit a new pair of corners, you can compare with the rectangles you currently have 'open' and determine what to do (close them, start new, divide, etc).
That statement isn't a complete solution, but I think it gets you from a complex solution to a simple one. It also doesn't seem to be NP complete in terms of performance. You might even be able to get O(n) perf.
An interesting problem. Let us know how you get on.
Look at the Region class.
Related
I'm still working on my first alghorithm to detect objects on simple image.
After few operations, my normal image looks like below one.
Part of images have normal, one big 'skeleton' It's all about threadshold. But when my first object is detected well, second one fails.
For solve this problem, I want to get Big rectangle from this picture. Are there any possibilities to find extreme points? Green one's on the image.
With these points I would like to create Rectangle.
Of course the next step to improve my code will be make better contour of object :)
Do you have any tips to do that?
Maybe others solutions?
I need to arrange tooltips for points that are located on a complex 2D shape.
The tooltips have different sizes
They must not obscure the shape itself
The lines that connect the tooltip to the points should not cross one each other.
The tooltip should be as mush closer to the point it belongs to.
I've tried several searches in google but nothing was close enough to what I need.
You've asked quite a doozy. I haven't personally worked on something like this, another SO member will likely be able to give you a complete solution. However, here are some points to consider when finding your solution.
1. The tooltips have different sizes
You will need a way determining this independently of your shape location algorythm. Performing the re-size as part of step 2 would make things much more complicated and may result in inconsistent behavior. So firstly, look into generating the dimensions of your tooltips.
2. They must not obscure the shape itself
In principle, you want a solution where the tooltip is not 'colliding' 'inside' the complex shape. Looking up '2d shape collision detection' would help here. You will need to know the dimensions of the shape of interest. You can't use a picture of a shape (unless you use a map of some sort). Most algorythms will require the following information for shapes containing concave points:
The points (2d vectors) that make up the complex shape
The points from which tooltips "spawn"
The tooltip dimensions (see point 1)
3. The lines that that connect the tooltip to a point should not cross eachover
This makes the problem significantly more complicated because it implies that multiple tooltips generated by #2 may be visible at the same time which will introduce alot of complexity.
Now you have N tooltips which need N locations occupying different areas which may not overlap, collide with the complex shape, or, when a line is drawn from them to point x, does not intersect any other lines from the remaining (N-1) shapes. It means the algorthm must be performed on the entire set and find the correct locations for all of them, a kind of three body problem.
4. The tooltip must be as close as possible to its associated point
This adds another small caveat which, because of stipulations set in #3 may not be able to be met 'ideally' (what if two shapes are colliding near two close points, which one 'wins out'?).
Again, these are some points to consider as you generate a solution. The result is that you have mathematically 'ideal' locations for your tooltips. However, with these considerations in mind, you may want to look into where realistic concessions may be made. If it's for a design project where the complex shape is unlikely to change then semimanual solutions may be better. If it's for a complex piece of software that will require automatically generated locations you may be able to redesign the UI to give the user the necessary feedback without such a complex solution.
A heuristic:
Compute the centroid of the points.
Place a circle, centered at the centroid, fully enclosing the shape.
Find the places on the circle, where a line form the center through each point
intersects the circle, i.e. project the points on the the circle.
These locations would serve as corners for the tooltip, depending on the which quadrant the point on the circle is, relative to the circle center.
You may increase the circle radius a bit, for aesthetic purposes :)
If I'm not mistaken, this should cover requirements (1), (2) and (3). For (4) you can refine the initial place by moving the tooltip towards the sphere center and checking for intersection with the shape, e.g. using binary search.
Something like this:
There are problems with this approach, of course, but nevertheless it may turn out to be a good starting point for refinement :)
I'm looking for an algorithm that can cut a shape with holes into shapes without holes. Language is preferably C#.
Here's an example image of such a shape.
I'd like to cut that shape into the least amount of smaller shapes without holes getting rid of most of the empty space (white). In this case this might probabyl be a bunch of rectangles. But the original shape might be more complex with rounded holes for example.
For me this sounds like some sort of a bin packing problem and therefore might be solved best with a genetical algorithm.
But in case you know a better approach, it's why I ask.
//edit: alright, I've obviously got some things to explain:
The shape is a Geometry object (WPF) resulting from the subtraction of a bunch of small Geometries from a larger Geometry. So I guess there are vertex points stored somewhere.
The amount of resulting shapes should be minimized, yes, the smallest set.
The resulting shapes should have edges that are as straight as possible with the smallest amount of corners possible.
Unfortunately, I can't provide any code, yet, since I have no clou whatsoever how to practically approach this programmatically. I'm really sorry.
The resulting shapes should be complex but don't have to.
To explain the reason for this: I'm working on a textile crafting (in particular patchworking) program with which one can create patchworks and calculate how much fabric is needed and the cost. Placing the patches on the fabric panel already works somehow using a Tetris like algorithm where patches get placed as close together as possible to reduce waste.
Additionally, everywhere the shape gets cut I need to add a seam allowance to the resulting parts (that's what you can already see in green in the example image).
//edit 2 An acceptable solution might look as follows. Red lines show where shape gets cut in order to get an amount of resulting shapes that don't have holes. The result set contains six large and 25 small rectangles:
However depending on the original shape which might look totally different, even with rounded edges (circular holes), acceptable solutions also might look different. The goal is to get rid of the white areas as far as possible while maintaining some convenience regarding the later actual cutting of the fabric. It'd be somehow counter-productive to have lots of shred that has to be sewed together again (and hence all need seam allowances) only to save a little bit fabric more.
I'm not sure how you want the resulting shapes to be but I'm going to assume that you want them in Polygon. As in an object Polygon which is a vector of 2D vertex points (x,y). What you can do now is use this Clipper library for solving geometric spatial problems. It does polygon subtraction, addition, intersection, and a bit more. Its also fast, free, and no license is needed.
http://sourceforge.net/projects/polyclipping/
Afterwards, you can calculate your seam lengths by just finding the distances along each polygon vertex and adding them up. However, this library does not support curved contours.
I have an abstract representation of a map with, lets say, 5.000.000 different integer coordinates on the X and Y coordinates, so it is a really big 2d rectangle.
And then, inside that variable-sized rectangle, I have several objects (characters, monsters, npcs). A player can select a position of this rectangle, and I have to check if there is a monster or a character on said position.
So far, I made a custom class called GameMatrix with columns and rows, and said columns has 3000x2000 positions (the area view of a character).
When a player of my game clicks on said coordinate, I have to do a foreach() of every element inside the matrix, and most of the times it is empty.
Is there a better way to solve this? Specifically, I am asking on what is the best way to, having a really big rectangle and a coordinate, check if there are objects inside said coordinate in an efficient way.
Forgot to mention, but this is done in the server-side several times per miliseconds. So I need a lot of performance.
Edit: Forgot to mention, I am using C#.
You should use a quad-tree implementation, unless the number of items in the grid is really small (like a couple of dozens items), in which case a linear search (brute force inspecting all of them at the same time) is probably the best choice.
See here
http://en.wikipedia.org/wiki/Quadtree
Note that a quad tree can be queried very quickly and efficiently, but updates are a bit more costly, that is if your items move a lot across your map, this becomes more complicated to do with a good performance.
I would recommend just trying the simplest solution first and worry about the optimization later.
Try using an array. Improve your solution as you go. A list or hash map might be interesting too depending on your setup.
I have problem optimizing drawing Google-like map. It works OK for hundreds of points, but when it comes to larger amounts like thousands it gets fuzzy and slow. Also unzoomed it looks weird.
I'd like to know how to optimize drawing algorithm to draw fewer places so it looks like unzooming on Google Maps.
However I also draw links between places, and I can't optimize that.
Please, post anything you can think of, I have to finish this and send it tomorrow.
Here's how it looks like:
zoomed in
zoomed out
Here's two ideas:
Every object that we draw on a map has an extra value in the database, "Zoom Level". When zooming in extra items will be shown based on that value.
A second way to this is to use grouping. If items start to overlap show one point with [10 items]. Only show the items beneath it when zooming in.
I think I would be tempted to not draw lines that are shorter than a threshold (and I mean this in terms of the viewport, not absolute distance terms). That means that when the map is zoomed out, you will have less to draw and the map will look less busy and when the map is zoomed in the lines between these nearby points will become visible. Edit: actually, thinking about it some more, I think I would only apply this length restriction when there are a large number of lines on screen — or make the length threshold a function of the number of lines on screen.
I think I would also be tempted to not draw lines that are from points that are off screen (out of the viewport) or, at least, quite a way off screen (a threshold away from the viewport's centre). I would suggest trying this change first.
These changes may seem like they will be hiding information (and they will) but, as it stands, the map is so busy this information presented is near useless anyway.
some hints:
clip region, to draw points only in the clip region
you can check opensource GIS project, see how they optimize drawing.