I am looking for a sound algorithm that would randomly place a given number of rectangles of the same size into a bigger rectangle (canvas).
I see two ways to do it:
create an empty array that will contain the rectangles already placed on canvas. start with the empty canvas. in a loop, pick a position at random for a new rectangle to be placed. check if the array has a rectangle that overlaps with the new rectangle. if it does not, put the new rectangle in to the array and repeat the loop. otherwise, pick a new position, and rerun the check again. and so on. This might never terminate (theoretically) I think. I do not like it.
use a grid and place rectangles into the cells randomly. This might still look like a grid placement. I do not like it either.
any better ways to do it? "better" meaning more efficient, or more visually "random" than the grid approach. better in any respect.
Here is a simple heuristic. It will be non-overlapping and random.
Place a rectangle randomly. Then, calculate the intersections of extensions of the the two parallel edges of the first rectangle with the edges of the canvas. You will obtain four convex empty regions. Place other rectangles in these empty regions one-by-one independently and calculate the similar divisions for placements. And try to put the remaining rectangles in empty regions.
You can try different strategies. You can try to place the rectangles close to the corners. Or, you can place them around the center of the regions. We cannot discuss optimality because you introduced randomness.
You might find Quadtrees or R-trees useful for your purpose.
I create internal room-like dungeons using the following method.
1) Scatter N points at random, but not within a few pixels of each other.
2) For each point in turn, expand if possible in all four directions. Cease
expanding if you hit another rectangle.
3) Cease the algorithm when no rooms can expand.
The result is N rectancles with just a few rectangular small spaces.
Code is in the binary image library
https://github.com/MalcolmMcLean/binaryimagelibrary/blob/master/dungeongenerator3.c
#
Related
Let's say for example I have a bitmap image of a tree, and I want to position other images (such as bitmaps of apples) on the tree leaves. Is there a way that I could put markers on the leaves... red dots for instance... and then and then programmatically place apple images centered on those dots?
As a very basic test, I have image with a white background with one red pixel in the center. I'd like to calculate the coordinates of this red point, and then set an ImageView to be placed on those coordinates.
How might I go about this?
It depends, where your 'red point' marker is. If it's in the center or in any specific point (like 2/3 of width, 1/3 of height), you can just divide layout width and height to get right coordinates.
In other cases it would be better to set white background and draw markers manually in overriden dispatchDraw method. In such case you would just know the coordinates of the marker.
You want to position an image over the red dot, right?
I'm thinking of two different ways:
A-> You could make the red dot to be an ImageView itself, and then centering it by using gravity in order to transform it into another kind of image.
Or...
B-> Make a container that uses the white background with red dot as background resource. Then center it by using gravity too, and finally, positioning your image to the center of the container so it will be over the red dot.
No calculation is needed if you thing this could help.
It sounds like you are the one putting the markers onto your bitmaps.
If that is the case, is there a really good reason why you would want to be trying to embed the markers as data in the bitmap itself? That leads you to the problem of having to rediscover the locations. This could be a fuzzy task...what if there is a red barn next to the tree? Are you going to put an apple image on every red pixel making up the barn?
What you might actually want is to define a format which has a bitmap with no markers on it, and then a separate list of coordinates for where you want the apples to go. That doesn't require discovery of any kind...you just ship the image along with the list and you are done.
There are some cases where there is no "place on the side" that you can put information, and you actually need it to go into the bitmap file. If so, consider also that there are some hidden places you can put data in bitmaps... metadata like Exif:
http://en.wikipedia.org/wiki/Exchangeable_image_file_format
So that's a middle-ground, where you can manage to get the list of points to "stow away" into the file containing the image without actually requiring the modification of the pixels.
If you find you are really stuck in a situation where you must put these coordinate specifications into the image data, then something a little bit more unique than a red dot would be easier to detect with certainty. Maybe there's something you know about your images... for instance, that they are PNG files and do not have any transparency. You could make transparent dots indicate substitution points.
The larger and weirder the pattern, the more rare it is...so if you know your objects being pasted are always going to be bigger than 3x3 you could come up with a very unusual 3x3 pixel imprint for your markers that would be unlikely to occur in nature. Uncompressed in 24-bit color, a sufficiently random pattern would only happen 1/(2^24^9) by accident. Small number; although compression would create more gray areas.
But greater point being: if you don't have a good reason to turn a simple problem into a complex image-recognition exercise, don't. Just keep the list of points on the side somewhere so you don't have to hunt for them in the image.
Am trying to break image in shattered pieces, but am unable to catch the logic, please give me way how to achieve.
I hope the below image can give my idea, what I want, Breaking the bitmap into a shattered pieces like triangle or any shape. later i will shuffle those bitmap shapes and giving puzzle to enduser rearrange them in order.
OK, if you want to rearrange the pieces (like in a jigsaw) then each triangle/polygon will have to appear in a rectangular bitmap with a transparent background, because that's how drawing bitmaps works in Java/Android (and most other environments).
There is a way to do this sort of masking in Android, its called porter-duff compositing. The Android documentation is poor to non-existent, but there are many articles on its use in Java.
Basically you create a rectangular transparent bitmap just large enough to hold your cut-out. Then you draw onto this bitmap a filled triangle (with transparency non-zero) representing the cut-out. It can be any colour you like. Then draw the cutout on top of the source image at the correct location using the Porter-Duff mode which copies the transparency data but not the RGB data. You will be left with your cutout against a transparent background.
This is much easier if you make the cutout bitmap the same size as the source image. I would recommend getting this working first. The downsides of this are twofold. Firstly you will be moving around large bitmaps to move around small cutouts, so the UI will be slower. Secondly you will use a lot of memory for bitmaps, and on some versions of Android you may well run out of memory.
But once you have it working for bitmaps the same size as the source image, it should be pretty straightforward to change it to work for smaller bitmaps. Most of your "mucking about" will be in finding and using the correct Porter-Duff mode. As there are only 16 of them, its no great effort to try them all and see what they do. And they may suggest other puzzle ideas.
I note your cutout sections are all polygons. With only a tiny amount of extra complexity, you could make them any shape you like, including looking like regular jigsaw pieces. To do this, use the Path class to define the shapes used for cutouts. The Path class works fine with Porter-Duff compositing, allowing cutouts of almost any shape you can imagine. I use this extensively in one of my apps.
I am not sure what puzzle game you are trying to make, but if there is no special requirements of the shattered pieces,
only the total number of them which can span the whole rectangle, you may try doing the following steps,
the idea is basically by knowing that n non-intersecting lines with two end points lie on any of the 4 edges of the rectangle, n+1 disjoint areas is formed.
Create an array and store the line information
For n times, you randomly pick two end points which lie on those 4 edges of the rectangle
2a. Try to join these two points: start from either end point, if you get an intersection with another line you drew before, stop at the intersection, otherwise stop at the other end point
You will get n+1 disjoint areas with n lines drawn
You may constrain your lines choosing if you have some special requirements of the areas.
For implementation details, you may want to have a look of dot product and euler's theorem
Recently I played a simple game on android called Pou, and one of it's inside games was a connect the dots on the field game. Here is a screenshot to better explain the situation.
At the beginning of the game you are given n-pairs of dots and you have to connect the same colored ones. While doing this you need to fill the matrix field.
Generating such a field is not a problem, but how can I be sure that it is solvable?
My question would be how can I generate a field that has a solution?
Is this a graph problem? Or some kind of a connectivity problem?
Of course I can always produce a brute force solution, but I am looking for something better
Actually you can generate the matrix in such a way that you can be sure it is solvable.
The main idea is as follow. Let say that you need i pairs of dots and the matrix is n by n
Set i randomly chosen cells (start points) as heads and to each assign a different color.
At each iteration for each color move its head randomly (left, right, up, down) into an uncolored cell and color it with i-th color. (if there is no legal such moves do not consider this color any more -- that will be the end point)
When you are finished and there is no uncolored cells you created a legal coloring of the board.
If there are some uncolored cells -- it may be quite challenging but for sure doable to modify / extend the coloring you obtained to fill those regions with some color -- the easiest way would be to exclude those regions from the matrix altogether :-)
Some other very loose thoughts:
each region that consists of more than 2 uncolored cells can be made legal (or at least some part of it) by assigning two additional dots to it;
you can split your initial n by n matrix into smaller rectangular parts and assign to each part some number of dots (proportional to the area) and use the above method -- for sure there will be less uncolored cells when you merge those parts back (on the other hand the puzzle will be bit easier).
UPDATE
once still in phase of coloring, if the next move produces a single, isolated cell: chose a different move and if no such move exists stop the coloring process for this color.
if you want to have a predefined number of dots (or the number close to it), check not only for single isolated cell, but for whole isolated regions. [btw. mind the possibility of coloring a candidate for isolation region by extending its start point]
for relative small n you can try using above method(s) until you hit full-coloring (so generate, check if legal, if not: generate again)
UPDATE II
If you have time you can try generating colors once at a time, with some probability of stopping, that depends on the length / area of the coloring. So basically just choose a random uncolored position and execute the above method. It should be easier to implement.
I have recently completed a simple drag and drop shapes game. It had the user drag a shape (ImageView) to another "empty place holder" ImageView.
I now want to make this a little more advanced, instead of dragging a simple shape, I want to make a puzzle of various non-orthogonal shapes, for example breaking a circle into 5 different pieces. What I'm having a problem with right now is how to design the layout. I do not know how to make a truly "custom" shaped ImageView, as far as I can find from my research it's not possible. So my idea for now is to overlap a number of square ImageViews, each of which will have only a subset of an image and the rest transparent. Thus the final output will look like it's a number of custom shaped ImageViews.
Example:
+ + +
Because only the internal sections are "visible" and the rest of the circle is transparent, when all of these pieces are placed in the same spot on the screen, the final image will look like:
I haven't tried this yet... but I foresee at least one problem. When I go to drag the pieces over to this puzzle, they will all "snap" into place when dragged to the same place. Because in reality all I really have here is a picture of a circle inside a ImageView which has some invisible rectangular boundary around it.
Hopefully this situation is clear. Now my questions:
Is it possible to have truly custom shaped ImageViews instead of my idea of overlapping images?
If what I'm thinking is the best way to handle this puzzle idea, then what property can be changed such that the "drop" action does not happen at the same place for all of these puzzle pieces? If I wanted to "drop" the pizza shaped piece, I'd like it to only snap into place when it go close to the top left of the circle.
Note: I am new to Android programming, and somewhat new to Java/XML as well, it’s very likely I’m overlooking something, so please feel free to suggest other approaches as you see fit.
Not really. Overlapping views is generally the way it's done. You could also use one View and override the drawing action yourself (multiple bitmaps drawn at relative locations within the View), but that would make the drag-drop aspect significantly harder.
If the Views are all the same size, with the visible portions in the correct relative placement in each, they should snap together correctly. This is because the snap is (I believe) based on the position of the upper-left corner of the View. If the pizza-shaped piece's visible portion is correct with regards to that, it should snap in at exactly the right spot.
So you have certain places you want to accept the drops, and I'm assuming you know their coordinates, say (d_x,d_y).
Then why not simply monitor the coordinate of the center (p_x,p_y) of image view of the piece you are dragging, say the "pizza" piece, and when the distance between the the piece and drop point is within an acceptable amount accept the drop.
But if you are asking if there is some way to make non-rectangular image views I don't believe that is possible.
However I don't think it is necessary in your case, because I believe even if you want them to drag the piece precisely into place you can calculate the coordinates where the draggable rectangle needs to go with knowledge of the shape of the piece and the assumption that the rectangle wraps the piece.
I'm trying to create a jigsaw puzzle app for Android. I am fairly far into the coding, and I am kind of stuck with one issue.
I need a way to change a Bitmap into a bunch of puzzle pieces. My current code simply cuts the image into rectangles, and it works pretty well, but now I need a way to create more complex piece shapes.
I had a couple of ideas:
Use a separate bitmap file that contains only black and white pixels, and use that to cut up the picture. I thought this was a pretty good plan, until I went to code it. I really had no idea how to do it.
Use a Path object to create the border. This would probably work, except I'm not sure how to keep track of the sides so that the pieces connect with each other.
Any ideas? I'm open to any suggestions.
You can use Path and/or Region to set a clip for your Canvas when drawing a Bitmap.
Take a look at this example. Here are some ways of clipping your drawing to any shape.
You could try making squares or rectangles fitted inside complex figures that can still be pieced toguether, when there's a match, the full rectangle covers the space. Imagine it like a 9 patch, when two sides match, you show the border rectangle.
This is not a explicit solution but I wonder if it would be possible to use bezier curves or paths to create lines along x and y , in conjunction with a parameter(fed with random value) to control the amount of deviation from a straight line and how much in a given distance ie; pixels/ per inch - this would be to create tongues on the pieces. Then use Region to extract the resulting shape at a given side of an intersection. Have the shape object get its center xy coordinate at instantiation and make it so that piece cannot be set if its current coordinate does not match the one it had when it was created.