admin管理员组

文章数量:1315832

I'm trying to use the Midpoint Displacement Algorithm using JavaScript and canvas as remended on gamedev.stackexchange.

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'm trying to use the Midpoint Displacement Algorithm using JavaScript and canvas as remended on gamedev.stackexchange..

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?

Share Improve this question edited Apr 13, 2017 at 12:18 CommunityBot 11 silver badge asked Mar 7, 2011 at 15:11 alexalex 491k204 gold badges889 silver badges991 bronze badges 2
  • You should be able to smooth it out by reducing the random number range. Did you try that already? – Matt Ball Commented Mar 7, 2011 at 15:15
  • @Matt Yeah, I tried a few things. I'm more interested if I have this algorithm correct first :) – alex Commented Mar 7, 2011 at 15:16
Add a ment  | 

2 Answers 2

Reset to default 11

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 putes 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);
};

The algorithm you have implemented is clearly wrong, from looking at the result. Where you went wrong is hard to say, since the code you have posted is not self contained. You are operating on several variables defined in a parent scope and it is not immediately apparent what they contain or how they behave.

What is terrain for example?

What you have to realize first of all is, that if the start and endpoints don't match on the y-axis you have done something wrong ;)

本文标签: canvasDoes this JavaScript code follow the Midpoint Displacement algorithmStack Overflow