Помогите с реализацией алгоритма Diamond Square - PullRequest
0 голосов
/ 12 сентября 2010

Я пытаюсь реализовать алгоритм Алмазный квадрат , но проблема в том, что заполняется только часть растрового изображения, и я не уверен, что не так. Я делаю это рекурсивно:

    GLuint CreateDsquare()
    {
        std::vector<GLubyte> pdata(256 * 256 * 4);


        vector2i loc;
        vector2i sz;
        GLubyte val;

        sz.x = 256;
        sz.y = 256;

        val = rand() % 255;

        loc = vector2i(0,0);

         pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
         pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
         pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
         pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;

        loc.x = sz.x - 1;
        loc.y = 0;

        val = rand() % 255;

        pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;

        loc.x = sz.x - 1;
        loc.y = sz.y - 1;

        val = rand() % 255;

        pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;

        loc.x = 0;
        loc.y = sz.y - 1;

        val = rand() % 255;

        pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
        pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;

        RescursiveDiamond(pdata,sz,vector2i(0,0));

        return CreateTexture(pdata,256,256);
    }

void RescursiveDiamond(std::vector<GLubyte> &pdata,vector2i psz, vector2i offset)
{
    int val;
    int newnum;
    if(psz.x < 2 && psz.y  < 2)
    {
        return;
    }


    vector2i loc;
    vector2i sz = psz;

    std::vector<int> pvertz(4,0);

    loc = offset;
    pvertz[0] = pdata[loc.y * 4 * sz.x + loc.x * 4 + 0];

    loc.x = offset.x + (psz.x - 1);
    loc.y = offset.y;
    pvertz[1] = pdata[loc.y * 4 * sz.x + loc.x * 4 + 0];

    loc.x = offset.x + (psz.x - 1);
    loc.y = offset.y + (psz.y - 1);
    pvertz[2] = pdata[loc.y * 4 * sz.x + loc.x * 4 + 0];

    loc.x = offset.x;
    loc.y = offset.y + (psz.y - 1);
    pvertz[3] = pdata[loc.y * 4 * sz.x + loc.x * 4 + 0];


    val = (pvertz[0] + pvertz[1]) / 2;
    val += 255;
    loc.x = (offset.x + (sz.x - 1)) / 2;
    loc.y = offset.y;

    pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;


    val = (pvertz[1] + pvertz[2]) / 2;
    val += 255;
    loc.x = (offset.x + (sz.x)) - 1;
    loc.y = ((offset.y + (sz.y)) / 2) - 1;

    pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;


    val = (pvertz[3] + pvertz[2]) / 2;
    val += 255;
    loc.x = ((offset.x + (sz.x)) / 2) - 1;
    loc.y = (offset.y + (sz.y)) - 1 ;

    pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;


    val = (pvertz[0] + pvertz[3]) / 2;
    val += 255;
    loc.x =  offset.x;
    loc.y = (offset.y + (sz.y)) - 1 ;

    pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;

    //center

    val = (pdata[(offset.y) * 4 * sz.x + ((offset.x + (sz.x - 1)) / 2) * 4 + 0] +
        pdata[(offset.y + (sz.y - 1)) * 4 * sz.x + ((offset.x + (sz.x - 1)) / 2) * 4 + 0]) / 2;

    int ad = (rand() % 12) - 6;
    if(val + ad < 0)
    {
        val = 0;
    }
    else
    {
        val += ad;
    }

    val += 255;

    loc.x =  ((offset.x + (sz.x) ) / 2) - 1;
    loc.y = ((offset.y + (sz.y)) / 2) - 1;

    pdata[loc.y * 4 * sz.x + loc.x * 4 + 0] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 1] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 2] = val;
    pdata[loc.y * 4 * sz.x + loc.x * 4 + 3] = 255;



    vector2i newoffset;
    vector2i newparentsz;

    newoffset = offset;
    newparentsz = (psz / 2);

    RescursiveDiamond(pdata,newparentsz,newoffset);

    newoffset.x = offset.x + (newparentsz.x);
    newoffset.y = offset.y;

    RescursiveDiamond(pdata,newparentsz,newoffset);


    newoffset.x = offset.x;
    newoffset.y = offset.y + (newparentsz.y);

    RescursiveDiamond(pdata,newparentsz,newoffset);
    newoffset.x = offset.x + (newparentsz.x);
    newoffset.y = offset.y + (newparentsz.y);

    RescursiveDiamond(pdata,newparentsz,newoffset);



}

Я подозреваю, что я мог вызвать функцию с неправильным смещением или что-то в этом роде.

Смещение похоже на верхний левый, а затем есть размер, вместе они сужают квадрат.

что тут может быть не так?

Спасибо

Ответы [ 2 ]

1 голос
/ 12 сентября 2010

Ладно, во-первых, давайте начнем с устранения нарушений D-R-Y , ваш код должен читаться так:

int position( _y, _x, _offset ){
    return _y * _x * 4 + _x * 4 + _offset;
}

void adjust(vector<GLubyte> &pdata, _x, _y){
    GLubyte val = rand() % 255;
    for(int j=0; j < 3; ++j){
        pdata[ position( _y, _x, j ) ] = val;
    }
    pdata[ position( _y, _x, 3 ) ] = 255;
}

GLuint CreateDsquare(){
    vector2i sz;

    sz.x = 256;
    sz.y = 256;

    adjust( pdata, 0, 0 );
    adjust( pdata, sz.x - 1, 0 );
    adjust( pdata, sz.x -1, sz.y - 1 );
    adjust( pdata, 0, sz.y - 1 );

    RescursiveDiamond(pdata,sz,vector2i(0,0));

    return CreateTexture(pdata,256,256);
}

Можете ли вы отформатировать остальное, чтобы оно было более читабельным / понятным? Затем я уточню, чтобы я мог лучше ответить на ваш вопрос (если кто-то не побил меня этим или женщина решает, что у меня достаточно времени на компьютере.)

0 голосов
/ 14 сентября 2010

Когда вы вычисляете смещение в вашей карте высот для каждой строки (y * pitch), вы используете текущий размер квадрата, который вы вычисляете, вместо фактического шага, равного 256. Чем глубже вы идете в рекурсии, тем большезаписываем в карту высот, как если бы она была все меньше и меньше, пока последний шаг вашей рекурсии не записывает в пиксели (0, 0).

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