帮助Diamond Square算法实现

时间:2010-09-11 21:01:53

标签: c++ c algorithm

我正在尝试实现Diamond-square algorithm,但问题只是位图的一部分正在填充,我不确定是什么问题。我是递归地做的:

    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 个答案:

答案 0 :(得分:1)

好的,首先,让我们从清除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);
}

你可以将其余部分格式化,以便更具可读性/可理解性吗?然后我会更新,以便我可以更好地回答你的问题(如果有人没有打败我,或者女人决定我有足够的电脑时间。)

答案 1 :(得分:0)

当您计算每行(y * pitch)的高度贴图的偏移量时,您使用的是您正在计算的平方的当前大小,而不是256的实际音高。您进入递归的深度越深正在写入你的高度图,好像它越来越小,直到递归的最后一步写入像素(0,0)。