Этот код JavaScript соответствует алгоритму смещения средней точки? - PullRequest
8 голосов
/ 07 марта 2011

Я пытаюсь использовать алгоритм смещения средней точки с использованием JavaScript и canvas, как рекомендовано для gamedev.stackexchange.com .

Приведенный ниже код генерирует точки, где индекс массива - это позиция x, а его значение - позиция y.

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(): min и max. width и height соответствуют canvas.

Это производит что-то вроде ... Canvas

Это выглядит довольно изменчиво, но это может быть просто так.

Правильно ли я понял этот алгоритм? Если нет, то что не так, и можете ли вы указать мне правильное направление?

Ответы [ 2 ]

11 голосов
/ 07 марта 2011

Я бы сказал, что это не похоже на смещение в средней точке, просто потому, что каждый сегмент должен иметь правильную длину оси X (у вас есть почти вертикальные сегменты). Вы пытались создать простой 4-сегментный массив? Как это выглядит?

Вот краткое руководство, которое я написал, вы можете увидеть его в действии: Алгоритм средней точки в Javascript

Исходный код:

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);
};
0 голосов
/ 07 марта 2011

Алгоритм, который вы реализовали, явно неверен, если смотреть на результат. Трудно сказать, где вы ошиблись, поскольку опубликованный вами код не является самодостаточным. Вы работаете с несколькими переменными, определенными в родительской области, и не сразу видно, что они содержат или как они себя ведут.

Что такое terrain например?

Прежде всего вы должны понять, что если начальная и конечная точки не совпадают на оси Y, вы сделали что-то не так;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...