Removing lakes from diamond square map - java

I implemented the diamond square algorithm in Java, but i'm not entirely satisfied with the results as a height map. It forms a lot of "lakes" - small areas of low height. The heights are generated using the diamond square algorithm, then normalized. In the example below, white = high, black = low and blue is anything below height 15: a placeholder for oceans.
This image shows the uncolored height map
How can I smooth the terrain to reduce the number of lakes?
I've investigated a simple box blurring function (setting each pixel to the average of its neighbors), but this causes strange artifacts, possibly because of the square step of the diamond square.
Would a different (perhaps gaussian) blur be appropriate, or is this a problem with my implementation? This link says the diamond square has some inherent issues, but these don't seem to be regularly spaced artifacts, and my heightmap is seeded with 16 (not 4) values.

Your threshold algorithm needs to be more logical. You need to actually specify what is to be removed in terms of size, not just height. Basically the simple threshold sets "sea level" and anything below this level will be water. The problem is that because the algorithm used to generate the terrain is does so in a haphazard way, small areas could be filled by water.
To fix this you need to essentially determine the size of regions of water and only allow larger areas.
One simple way to do this is to not allow single "pixels" to represent water. Essentially either do not set them as water(could use a bitmap where each bit represents if there is water or not) or simply raise the level up. This should get most of the single pixels out of your image and clear it up quite a bit.
You can extend this for N pixels(essentially representing area). Basically you have to identify the size of the regions of water by counting connected pixels. The problem is this, is that it allows long thin regions(which could represent rivers).
So it it is better to take it one step further and count the width and length separate.
e.g., to detect a simple single pixel
if map[i,j] < threshold && (map[i-1,j-1] > threshold && ... && map[i+1,j+1] > threshold) then Area = 1
will detect isolated pixels.
You can modify this to detect larger groups and write a generic algorithm to measure any size of potential "oceans"... then it should be simple to get generate any height map with any minimum(and maximum) size oceans you want. The next step is to "fix" up(or use a bitmap) the parts of the map that may be below sea level but did not convert to actual water. i.e., since we generally expect things below sea level to contain water. By using a bitmap you can allow for water in water or water in land, etc.
If you use smoothing, it might work just as well but you still will always run in to such problems. Smoothing reduces the size of the "oceans" but a large ocean might turn in to a small one and a small one eventually in to a single pixel. Depending on the overall average of the map, you might end up with all water or all land after enough iterations. Blurring also reduces the detail of the map.
The good news is, that if you design your algorithm with controllable parameters then you can control things like how many oceans are in the map, or how large they are, how square they are(or how circular if you want), or how much total water can be used, etc).
The more effort you put in to this you more accurate you can simulate reality. Ultimately, if you want to be infinitely complex you can take in to account how terrains are actually formed, etc... but, of course, the whole point of these simple algorithms is to allow them to be computable in reasonable amounts of time.

Related

When Java draws something outside of canvas, will it affect performance?

If I draw something with coordinations like -80 and -90 will it affect performance same way as if it was actually drawn inside?
Is it actually worth it checking if the final image will appear on screen?
(and not drawing it if won't)
If I draw something with coordinations like -80 and -90 will it affect performance same way as if it was actually drawn inside?
Somewhat, but not nearly as much as if it is inside the screen.
Is it actually worth it checking if the final image will appear on screen? (and not drawing it if won't)
It's practically never worth implementing your own culling/clipping in a library where drawing out of bounds isn't an error/access violation, since the library would already have to make that check to avoid writing to memory out of bounds, and it would generally be wise to bet that the library's way of checking this is smart and fast.
So if you were to add your own basic check on top, now you're just making the regular, on-screen drawing perform two of such checks (your own on top of whatever is going on under the hood), and for off-screen cases, it would be likely that your check would actually be slower (or at least no better) than the library's.
Now I have to place emphasis on basic culling/clipping here. By basic, I mean checking for each shape you draw on a per-shape basis. There you'll just more likely damage performance.
Acceleration Structures and Clipping/Culling in Bulk
Yet there are cases where you might have a data structure to do efficient culling of thousands of triangles at once with a single bounding box check to see if it's in the frustum, for example, in a 3D case with structures like bounding volume hierarchies. Games use these types of data structures to massively reduce the amount of drawing requests required per frame with very few checks, and there you do gain a potentially massive performance benefit. A more basic version of this is simply check if the object/mesh containing the triangles has a bounding box that is inside the screen, eliminating potentially thousands of triangles from being culled individually with a single bounding box check.
In 2D with clipping, you might be able to use something like a quad tree or fixed grid to only selectively draw what's on the screen (and also accelerate collision detection or click-detection, e.g.). There you might actually get a performance boost if you can eliminate many superfluous drawing calls with a single check. But again, that's using a data structure that eliminates a boatload of unnecessary drawing calls with a single check. These are spatial partitioning structures whose sole point is to avoid checking things on a per-shape basis.
For a more basic 2D example, if you have say, a 2D "widget" which, in order to draw it, involves drawing dozens of different shapes to the screen, you might be able to squeeze a performance gain if you can avoid requesting to draw dozens of shapes with a single check to see if the rectangle encompassing the entire widget is in the screen. Again, there you're doing one check to eliminate many drawing calls. You won't get a performance gain on a level playing field where you're doing that check on a per-shape basis, but if you can turn many checks into a single check, then you have a chance.
According to the Graphics implementation for most common draws/fills (i.e. drawRectangle see: source of Graphics on grepcode.com they start with checking if the width and height are bigger then zero and then are doing more operations, therefore doing check for x,y < 0 are in doing the same number of operations in worst case.
Keep in mind that a rectangle starting at -80 and -90 as you said but width and height i.e. 200 will be displayed on screen.
Yes it will still affect the performance as it still does exist within the program, it's just not visible on the screen

Libgdx - TexturePacker combination of texture filters

apologies as this is a common topic and haven't found a widely-agreed on solution.
We have a game world "grid" size of 1220 x 1080 (based on our Designer's photoshop designs). Currently we test on a Nexus 4 (1280x768 #320DPI) and TF201 Transformer Prime Tablet (1280x800 #149DPI).
When packing textures, with the TexturePacker, we're a bit confused about which combination of filters to use. We've read the following page:
http://www.badlogicgames.com/wordpress/?p=1403
.. and when using "Nearest, Nearest", our FPS was fine at 60, but assets became pixelated. Now we packed using "Mipmap, Mipmap", and our FPS went down to 30, but the textures are smoothly edged again.
Is there an agreed upon combination of these filters, or are they simply dependent on requirements? There are quite a lot of combinations to set for "min filter" and "mag filter" in the Packer, so don't want to keep randomly setting them until everything is smoothly resized and FPS is high again, without fully understanding what it is doing.
Many thanks.
J
If you are supporting multiple screen sizes (which you are if targeting Android), the Mag filter should always be Linear. There is no such thing as a mip-mapped mag filter, and on some devices that won't even work (you'll get pure black). It's kind of a "gotcha", because some devices will just assume you meant Linear and fix it for you, so if you fail to test on a device that doesn't do this for you, you'll be unaware of the problem. Nearest will look pixelated when stretched bigger, and you would only want to use it if your are doing retro low resolution graphics, or drawing something pixel perfect.
You can choose one of the following for the Min filter, from fastest (and worst looking) to slowest (and best looking):
Nearest - this will look pixelated and I can't think of any situation where this would be the right choice for a min filter.
MipMapNearestNearest - Won't look or perform better than nearest, and uses more memory. No reason to ever use this.
MipMapNearestLinear - Gets the nearest pixel from the two nearest mips and then linearly interpolates between them. This will still look pixelated. I don't think this is ever used either.
MipMapLinearNearest - Gets the nearest mip level and linearly determines the pixel color. This is most commonly used on mobile for smooth graphics, I think. It performs significantly faster than the below option, but there are cases where it will look slightly blurry (when the nearest mip is kind of on the small side for what's on screen).
MipMapLinearLinear - Gets the two nearest mip levels, linearly determines the pixel color on each of them, and then linearly blends between the two. If you have a sprite that shrinks from nothing to full size, you probably won't be able to detect any difference in quality from smallest to largest. But this is also slow. In the past, I have limited its use to my fonts. I have also done one project that could run at 60fps on new devices three years ago, where I used this on everything. I was very careful about overdraw in that app, so I could get away with it.
Finally, there's linear filtering, which looks and performs worse than the mip-mapping options (for a Min filter):
Linear - this will look smooth if the image is slightly smaller on screen than its original texture. This doesn't use up the 33% extra texture memory that mip mapping does, but the performance will be worse than it would with mip mapping if the texture gets any smaller than 50% of the original, because for each screen pixel it will have to sample and blend more than four pixels from the original texture.

Programmatically find shaky OR out-of-focus Images

Most modern mobile cameras has a family of techniques called Image Stabilization to reduce shaky effects in photographs due the motion of the camera lens or associated hardware. But still quite a number of mobile cameras produce shaky photographs. Is there a reliable algorithm or method that can be implemented on mobile devices, specifically on Android for finding whether a given input image is shaky or not? I do not expect the algorithm to stabilize the input image, but the algorithm/method should reliably return a definitive boolean whether the image is shaky or not. It doesn't have to be Java, but can also be C/C++ so that one can build it through the native kit and expose the APIs to the top layer. The following illustration describes the expected result. Also, this question deals with single image problems, thus multiple frames based solutions won't work in this case. It is specifically about images, not videos.
Wouldn't out of focus images imply that
a) Edges are blurred, so any gradient based operator will have a low values compared to the luminance in the image
b) edges are blurred, so any curvature based operator will have low values
c) for shaky pictures, the pixels will be correlated with other pixels in the direction of the shake (a translation or a rotation)
I took your picture in gimp, applied Sobel for a) and Laplacian for b) (available in openCV), and got images that are a lot darker in the above portion.
Calibrating thresholds for general images would be quite difficult I guess.
Are you dealing with video stream or a single image
In case of video stream: The best way is calculate the difference between each 2 adjacent frames. And mark each pixel with difference. When the amount of such pixels is low - you are in a non shaky frame. Note, that this method does not check if image is in focus, but only designed to combat motion blur in the image.
Your implementation should include the following
For each frame 'i' - normalize the image (work with gray level, when working with floating points normalize the mean to 0 and standard deviation to 1)
Save the previous video frame.
On each new video frame calculate pixel-wise difference between the images and count the amount of pixels for whom the difference exceed some threshold. If the amount of such pixels is too high (say > 5% of the image) that means that the movement between the previous frame and current frame is big and you expect motion blur. When person holds the phone firmly, you will see a sharp drop in the amount of pixels that changed.
If your images are represented not in floating point but in fixed point (say 0..255) than you can match the histograms of the images prior to subtraction in order to reduce noise.
As long as you are getting images with motion, just drop those frames and display a message to the user "hold your phone firmly". Once you get a good stabilized image, process it but keep remembering the previous one and do the subtraction for each video frame.
The algorithm above should be strong enough (I used it in one of my projects, and it worked like a magic).
In case of Single Image: The algorithm above does not solve unfocused images and is irrelevant for a single image.
To solve the focus I recommend calculating image edges and counting
the amount of pixels that have strong edges (higher than a
threshold). Once you get high amount of pixels with edges (say > 5%
of the image), you say that the image is in focus. This algorithm is far from being perfect and may do many mistakes, depending on the texture of the image. I recommend using X,Y and diagonal edges, but smooth the image before edge detection to reduce noise.
A stronger algorithm would be taking all the edges (derivatives) and calculating their histogram (how many pixels in the image had this specific edge intensity). This is done by first calculating an image of edges and than calculating a histogram of the edge-image. Now you can analyse the shape of the histogram (the distribution of the edges strength). For example take only the top 5% of pixels with strongest edges and calculate the variance of their edge intensity.
Important fact: In unfocused images you expect the majority of the pixels to have very low edge response, few to have medium edge response and almost zero with strong edge response. In images with perfect focus you still have the majority of the pixels with low edge response but the ratio between medium response to strong response changes. You can clearly see it in the histogram shape. That is why I recommend taking only a few % of the pixels with the strongest edge response and work only with them. The rest are just a noise. Even a simple algorithm of taking the ratio between the amount of pixels with strong response divided by the amount of pixels with medium edges will be quite good.
Focus problem in video:
If you have a video stream than you can use the above described algorithms for problematic focus detection, but instead of using constant thresholds, just update them as the video runs. Eventually they will converge to better values than a predefined constants.
Last note: The focus detection problem in a single image is a very tough one. There are a lot of academic papers (using Fourier transform wavelets and other "Big algorithmic cannons"). But the problem remains very difficult because when you are looking at a blurred image you cannot know whether it is the camera that generated the blur with wrong focus, or the original reality is already blurred (for example, white walls are very blurry, pictures taken in a dark tend to be blurry even under perfect focus, pictures of water surface, table surface tend to be blurry).
Anyway there are few threads in stack overflow regarding focus in the image. Like this one. Please read them.
You can also compute the Fourier Transform of the image and then if there is a low accumulation in the high frequencies bins, then the image is probably blurred. JTransform is a reasonable library that provides FFT's if you wish to travel down this route.
There is also a fairly extensive blog post here about different methods that could be used
There is also another stack overflow question asking this but with OpenCV, OpenCV also has Java bindings and can be used in Android projects so this answer could also be helpful.

Tiled Terrain Generation with Perlin Noise - Java

I'm currently generating 2d Perlin noise to a 2d array and (after interpolation) rendering the results held as a height map (essentially array[x][z] = y).
This is fine for one array, but not for tile loading based on the camera position, and I'm having difficulty where the tiles should meet at the seam.
[Noise Tiles]
My best attempt has been to generate a large 2d array of the base noise (-1 to 1), then have each tile as an object that stores an offset value for the base grid (which part of the noise to read).
This has allowed me to sample (for interpolation) areas of the base grid that are much larger than the tile array, but it still not lining up!
My objective is to have a flycam that loads tiles as it moves, and can travel very far without repeating.
Is this approach of 2d arrays solid enough to handle the objective?
If so, how can it be implemented to tile or wrap correctly?
I have had similar problems before and after alot of tweaking and testing I've come to the conclusion that just plain 2D perlin noise as is will never look like natural terrain, it's essentially white noise(ie no huge mountains or valleys, just hills close together)
What I recently found as the way to go is by making a fractal out of multiple Perlin Noises but with different "resolutions" -if you will, added together to get custom terrain resolution using different octaves(ie higher octave = higher noise in your terrain). I usually go about using gain = 0.5(this really do not have to be changed much, it looks pretty good as is), and octaves = ~16
Note; this is made in processing, Java might have some different syntax, but it should be quite the same
float fractal(int x,int y,float gridSubs,float gain,int octaves){
float total = 0;
float freq = 1.0/gridSubs;
float amp = gain;
for(int f=0;f<octaves;f++){
total += noise(x*freq,y*freq)*amp;
freq *= 2.0;
amp *= gain;
}
return total;
}
Website where I found it: here
If you replace your noise() function with this you might get better looking results in the end.
As for your problem with your seams you probably have the coordinate offset in the noise function call for each chunk set wrongly, it should look somewhat like this:
noise( localX * tileSize + (chunkX * chunkSize) , localZ * tileSize + (chunkZ * chunkSize) );
You might have to add some resolution koefficent to make the noise somewhat smooth.
Now You said you are storing the heightvalues in a 2D heightMap, now that is fine and makes the heightvalues easy to access if you need to update them often or need to access them easily.
The problem with this is the size of the array easily get very large, and by that I mean, Very large. With my past experiences I could get a small map(can't remember size, but smaller than yours) to eat up 4Gb of my RAM just by loading it. I did use a float array though so using an integer array could have reduced the memory usage slightly.
How I do it now is I just recalculate each point in the terrain whenever I need to update the geometry, how I currently have set it up it does introduce a slight lagspike each time the terrain is changed when moving around. The benefit is that I can have a 4times larger map with greater detail and still use about 1-2Gb of RAM.
Since what I understood, you simply want to move around the terrain and look at it. This would benefit from not storing the heightmap in an array, since you do not really need the values after you have generated the terrain(this may differ if you are manually smoothing out the terrain).
One last thing to note; I am not an professional programmer, this is just what I have learned from my past experiences using randomly generated noise.

Getting boundary information from a 3d array

Hey, I'm currently trying to extract information from a 3d array, where each entry represents a coordinate in order to draw something out of it. The problem is that the array is ridiculously large (and there are several of them) meaning I can't actually draw all of it.
What I'm trying to accomplish then, is just to draw a representation of the outside coordinates, a shell of the array if you'd like. This array is not full, can have large empty spaces with only a few pixels set, or have large clusters of pixel data grouped together. I do not know what kind of shape to expect (could be a simple cube, or a complex concave mesh), and am struggling to come up with an algorithm to effectively extract the border. This array effectively stores a set of points in a 3d space.
I thought of creating 6 2d meshes (one for each side of the 3d array), and getting the shallowest point they can find for each position, and then drawing them separetly. As I said however, this 3d shape could be concave, which creates problems with this approach. Imagine a cone with a circle on top (said circle bigger than the cone's base). While the top and side meshes would get the correct depth info out of the shape, the bottom mesh would connect the base to the circle through vertical lines, making me effectivelly loose the conical shape.
Then I thought of annalysing the array slice by slice, and creating 2 meshes from the slice data. I believe this should work for any type of shape, however I'm struggling to find an algorithm which accuratly gives me the border info for each slice. Once again, if you just try to create height maps from the slices, you will run into problems if they have any concavities. I also throught of some sort of edge tracking algorithm, but the array does not provide continuous data, and there is almost certainly not a continuous edge along each slice.
I tried looking into volume rendering, as used in medical imaging and such, as it deals with similar problems to the one I have, but couldn't really find anything that I could use.
If anyone has any experience with this sort of problem, or any valuable input, could you please point me in the right direction.
P.S. I would prefer to get a closed representation of the shell, thus my earlier 2d mesh approach. However, an approach that simply gives me the shell points, without any connection between them, that would still be extremely helpful.
Thank you,
Ze
I would start by reviewing your data structure. As you observed, the array does not maintain any obvious spatial relationships between points. An octree is a pretty good representation for data like you described. Depending upon the complexity of you point set, you may be able to find the crust using just the octree - assuming you have some connectivity between near points.
Alternatively, you may then turn to more rigorous algorithms like raycasting or marching cubes.
Guess, it's a bit late by now to be truly useful to you, but for reference I'd say this is a perfect scenario for volumetric modeling (as you guessed yourself). As long as you know the bounding box of your point cloud, you can map these coordinates to a voxel space and increase the density (value) of each voxel for each data point. Once you have your volume fully defined, you can then use the Marching cubes algorithm to produce a 3D surface mesh for a given threshold value (iso value). That resulting surface doesn't need to be continuous, but will wrap all voxels with values > isovalue inside. The 2D equivalent are heatmaps... You can refine the surface quality by adjusting the iso threshold (higher means tighter) and voxel resolution.
Since you're using Java, you might like to take a look at my toxiclibs volumeutils library, which also comes with sevaral examples (for Processing) showing the general approach...
Imagine a cone with a circle on top
(said circle bigger than the cone's
base). While the top and side meshes
would get the correct depth info out
of the shape, the bottom mesh would
connect the base to the circle through
vertical lines, making me effectivelly
loose the conical shape.
Even an example as simple as this would be impossible to reconstruct manually, let alone algorithmically. The possibility of your data representing a cylinder with a cone shaped hole is as likely as the vertices representing a cone with a disk attached to the top.
I do not know what kind of shape to
expect (could be a simple cube...
Again, without further information on how the data was generated, 8 vertices arranged in the form of a cube might as well represent 2 crossed squares. If you knew that the data was generated by, for example, a rotating 3d scanner of some sort then that would at least be a start.

Categories