I'm trying to use the Midpoint Displacement Algorithm using JavaScript and canvas as recommended on gamedev.stackexchange.com.
The code below generates points where the array index is the x position and its value is the y position.
var createTerrain = function(chops, range) {
    chops = chops || 2;
    range = parseInt(range || 100); 
    if (chops > 8) return;
    var cycle = parseInt(width / chops);    
    for (var i = 0; i <= width; i += cycle) {
        var y = (height / 2) + getRandomNumber(-range, range);
        terrain[i] = y;
    }
    chops *= 2;
    range *= 0.5;
    createTerrain(chops, range);
}
getRandomNumber()'s arguments are min and max. width and height are respective of the canvas.
This produces something like...

It seems pretty choppy, but that may just be how it is.
Have I got this algorithm right? If not, what is wrong, and can you point me in the right direction?
I'd say it does not look like mid-point displacement, simply because every segment should be getting a regular X axis length (you have nearly vertical segments). Have you tried to generate a simple 4-segment array? What does it look like?
Here is a short tutorial I wrote, you can see it in action: Mid-point algorithm in Javascript
The source code:
function Terrain(segmentCount) {
    this.segmentCount = segmentCount;
    this.points = [];
    for (i=0; i<=segmentCount; ++i) {
        this.points[i] = 0;
    }
};
/**
* Generate the terrain using the mid-point displacement algorithm. This is in fact
* a shortcut to the recursive function with the appropriate value to start
* generating the terrain.
*
* @param maxElevation the maximal vertical displacement to apply at this iteration
* @param sharpness how much to attenuate maxElevation at each iteration (lower
*        value means a smoother terrain). Keep between 0 and 1.
*/
Terrain.prototype.generateUsingMidPoint = function(maxElevation, sharpness) {
    this.midPoint(0, this.segmentCount, maxElevation, sharpness);
}
/**
* This is the recursive function to actually generate the terrain. It computes a new height for the point
* between "start" and "end" (the mid-point): averages start and end heights and adds a random
* displacement.
*
* @param maxElevation the maximal vertical displacement to apply at this iteration
* @param sharpness how much to attenuate maxElevation at each iteration (lower
*        value means a smoother terrain). Keep between 0 and 1.
*/
Terrain.prototype.midPoint = function(start, end, maxElevation, sharpness) {
    var middle = Math.round((start + end) * 0.5);
    if ((end-start<=1) || middle==start || middle==end) {
        return;
    }
    var newAltitude = 0.5 * (this.points[end] + this.points[start]) + maxElevation*(1 - 2*Math.random());
    this.points[middle] = newAltitude;
    this.midPoint(start, middle, maxElevation*sharpness, sharpness);
    this.midPoint(middle, end, maxElevation*sharpness, sharpness);
};
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With