algorithm - मकथ - एक वर्ग ग्रिड पर संरचना की तरह एक शाखा की नस/नदी बनाने के तरीके




ब्रह्मपुत्र नदी वीडियो (2)

आपकी नदी डेल्टा बहुत पेड़ की तरह दिखती है यहां कुछ पेयथन कोड हैं जो कछुओं का उपयोग पेड़ों को आकर्षित करने के लिए ग्राफिक्स के लिए करते हैं।

# आप इस कोड को संपादित कर सकते हैं और ब्राउज़र में इसे ठीक से चला सकते हैं! # रंग बदलने या अपने स्वयं के आकार जोड़ने का प्रयास करें

import turtle
from random import randint

def tree(length,n, ps):
    """ paints a branch of a tree with 2 smaller branches, like an Y"""
    if length < (length/n):
           return       # escape the function
    turtle.pensize(max(ps,1))     
    turtle.forward(length)        # paint the thik branch of the tree
    lb = 45+randint(-20,20)
    turtle.left(lb)          # rotate left for smaller "fork" branch
    tree(length * 0.5*(1+randint(-20,20)/100),length/n,ps-1) # create a smaller branch with 1/2 the lenght of the parent branch
    rb = 45+randint(-20,20)
    turtle.right(lb+rb)         # rotoate right for smaller "fork" branch
    tree(length * 0.6,length/n,ps-1)      # create second smaller branch
    turtle.left(rb)          # rotate back to original heading
    rt = randint(-20,20)
    turtle.right(rt)
    tree(length * 0.45,length/n,ps-1)
    turtle.left(rt)
    turtle.backward(length)       # move back to original position
    return              # leave the function, continue with calling program
turtle.left(90)
turtle.penup()
turtle.backward(250)
turtle.pendown()
tree(150,5,5)

मैं प्रक्रियात्मक रूप से कुछ नदियों को बनाने की कोशिश कर रहा हूं।

मेरे पास एक फ्लैट (ऊँचाई का कोई अवधारणा) वर्ग ग्रिड नहीं है और छवि पर दिखाए जाने पर उस पर एक शाखा की संरचना तैयार करना चाहते हैं।

क्या आप ये कदम उठाने के लिए उपयोग कर सकते हैं?

मैं सबसे तेज़ क्रियान्वयन की तलाश नहीं कर रहा हूं क्योंकि कोई वास्तविक समय पीढ़ी नहीं है, लेकिन सरल कार्यान्वयन को प्राथमिकता दी जाएगी। लू मेरी भाषा है लेकिन कुछ भी करेंगे

कुछ और चीज़ें:

  1. आकृति एल्गोरिथम सहयोगी उत्पन्न होनी चाहिए।
  2. बीज मूल्य का उपयोग करके आकार को नियंत्रित किया जाना चाहिए।


मुझे लगता है कि नदियों का उत्पादन एक पिछड़ा दृष्टिकोण है जैसा आपको बाद में उनके आकार के अनुसार कई चीजों को ज़्यादा प्रभावित करने की आवश्यकता होगी, जिस पर मुश्किल होगा। मैं इसके बजाय यादृच्छिक इलाके की ऊँचाई नक्शा बनाने और इसके बारे में सुविधाओं को निकालने (असली दुनिया की तरह), जो कि बहुत आसान और वास्तविकता के करीब है अंतिम नक्शे में आप ऊंचाई की उपेक्षा करते हैं और फ्लैट का उपयोग करते हैं (यदि आप वास्तव में एक फ्लैट नक्शा चाहते हैं)। यहां कुछ चीजें हैं जो आप ऊंचाई मानचित्र से निकाल सकते हैं:

  1. नदियां और झीलें

    यादृच्छिक उच्च ऊंचाई बिंदु को सीधा करके और डाउनहिल का अनुसरण करके समुद्र के स्तर या नक्शे के किनारे पर।

  2. वनस्पति या जमीन

    ढलान और ऊंचाई से आप निर्धारित कर सकते हैं कि जमीन रेत, गंदगी, रॉक है यदि पेड़ों, झाड़ियों, घास या जो भी हो

यहां इस QA को देखें : यादृच्छिक द्वीप जनरेटर

और कुछ नदी का अवलोकन:

जिस तरह से आप इलाके की पीढ़ी को प्रभावित करते हैं, वह नदी के आकार को भी प्रभावित करेगी (सिर्फ द्वीपों को पैदा करने की आवश्यकता नहीं है)।

बीज इस दृष्टिकोण के लिए भी काम कर रहे हैं।

[संपादन 1] सी ++ कोड का वादा किया

यह मूल रूप से यादृच्छिक ऊंचाई मानचित्र उत्पन्न करता है और तब बीज और डाउनहिल नदियों का अनुसरण करते हैं (अगर झीलों को स्वचालित रूप से उत्पन्न किया जाता है तो इलाके ब्लॉक डाउनहिल मेटर प्रवाह)। इलाके का प्रकार ढलान और ऊंचाई से भी निर्धारित होता है।

//---------------------------------------------------------------------------
picture pic;
//---------------------------------------------------------------------------
void map_random(int _xs,int _ys)
    {
    // config
    int   h0=-1000,h1=3000;     // [m] terrain elevation range
    int   h_water= 0;           // [m] sea level
    int   h_sand=15;            // [m] sand level
    int   h_evergreen=1500;     // [m] evergreen level
    int   h_snow=2000;          // [m] snow level
    int   h_rock=1800;          // [m] mountine rock level
    float a_rock=60.0;          // [deg] mountine rock slope
    float d_pixel=35.0;         // [m] pixel size
    int   d_river_w=5;          // [pixel] river max width
    int   d_river_l=150;        // [pixel] river base length per width increase
    bool _island=true;

    // types
    enum _cover_enum
        {
        _cover_none=0,
        _cover_water,   // sea
        _cover_snow,
        _covers,
        _cover_shift=0,
        _cover_mask=15,
        };
    DWORD _cover[_covers]=
        {
        //  RRGGBB
        0x00000000,     // none
        0x00003080,     // watter (sea)
        0x00EEEEEE,     // snow
        };
    enum _terrain_enum
        {
        _terrain_dirt=0,
        _terrain_sand,
        _terrain_rock,
        _terrain_water, // streams,rivers,lakes
        _terrain_temp,  // temp
        _terrains,
        _terrain_shift=4,
        _terrain_mask=15,
        };
    DWORD _terrain[_terrains]=
        {
        //  RRGGBB
        0x00301510,     // dirt
        0x00EEC49A,     // sand
        0x006F6F6F,     // rock
        0x00006080,     // water (streams,rivers,lakes)
        0x00006080,     // temp
        };
    enum _flora_enum
        {
        _flora_none=0,
        _flora_grass,
        _flora_hardwood,
        _flora_evergreen,
        _flora_deadwood,
        _floras,
        _flora_shift=8,
        _flora_mask=15,
        };
    DWORD _flora[_floras]=
        {
        //  RRGGBB
        0x00000000,     // none
        0x007F7F3F,     // grass
        0x001FFF1F,     // hardwood
        0x00007F00,     // evergreen
        0x007F3F1F,     // deadwood
        };

    // variables
    float a,b,da; int c,t,f;
    int x,y,z,xx,yy,mxs,mys,dx,dy,dx2,dy2,r,r2,ix,l;
    int xh1,yh1;    // topest hill position
    int **ter=NULL,**typ=NULL;
    Randomize();
    // align resolution to power of 2
    for (mxs=1;mxs+1<_xs;mxs<<=1); if (mxs<3) mxs=3;
    for (mys=1;mys+1<_ys;mys<<=1); if (mys<3) mys=3;
    ter=new int*[mys+1]; for (y=0;y<=mys;y++) ter[y]=new int[mxs+1];
    typ=new int*[mys+1]; for (y=0;y<=mys;y++) typ[y]=new int[mxs+1];

    // [Terrain]
    for (;;)
        {
        // diamond & square random height map -> ter[][]
        dx=mxs; dx2=dx>>1; r=(mxs+mys)<<1;          // init step,half step and randomness
        dy=mys; dy2=dy>>1; r2=r>>1;
        // set corners values
        if (_island)
            {
            t=-r2;
            ter[  0][  0]=t;
            ter[  0][mxs]=t;
            ter[mys][  0]=t;
            ter[mys][mxs]=t;
            ter[dy2][dx2]=r+r;  // top of central hill
            }
        else{
            ter[  0][  0]=Random(r);
            ter[  0][mxs]=Random(r);
            ter[mys][  0]=Random(r);
            ter[mys][mxs]=Random(r);
            }
        for (;dx2|dy2;dx=dx2,dx2>>=1,dy=dy2,dy2>>=1)    // subdivide step until full image is filled
            {
            if (!dx) dx=1;
            if (!dy) dy=1;
            // diamond (skip first one for islands)
            if ((!_island)||(dx!=mxs))
             for (y=dy2,yy=mys-dy2;y<=yy;y+=dy)
              for (x=dx2,xx=mxs-dx2;x<=xx;x+=dx)
               ter[y][x]=((ter[y-dy2][x-dx2]+ter[y-dy2][x+dx2]+ter[y+dy2][x-dx2]+ter[y+dy2][x+dx2])>>2)+Random(r)-r2;
            // square
            for (y=dy2,yy=mys-dy2;y<=yy;y+=dy)
             for (x=dx ,xx=mxs-dx ;x<=xx;x+=dx)
              ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y-dy2][x]+ter[y+dy2][x])>>2)+Random(r)-r2;
            for (y=dy ,yy=mys-dy ;y<=yy;y+=dy)
             for (x=dx2,xx=mxs-dx2;x<=xx;x+=dx)
              ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y-dy2][x]+ter[y+dy2][x])>>2)+Random(r)-r2;
            for (x=dx2,xx=mxs-dx2;x<=xx;x+=dx)
                {
                y=  0; ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y+dy2][x])/3)+Random(r)-r2;
                y=mys; ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y-dy2][x])/3)+Random(r)-r2;
                }
            for (y=dy2,yy=mys-dy2;y<=yy;y+=dy)
                {
                x=  0; ter[y][x]=((ter[y][x+dx2]+ter[y-dy2][x]+ter[y+dy2][x])/3)+Random(r)-r2;
                x=mxs; ter[y][x]=((ter[y][x-dx2]+ter[y-dy2][x]+ter[y+dy2][x])/3)+Random(r)-r2;
                }
            if (_island)
                {
                // recompute middle position after first pass so there can be more central hills
                if (dx==mxs) ter[dy2][dx2]=Random(r2);
                // adjust border to underwatter
                for (y=0;y<=mys;y+=dy2) { ter[y][0]=t; ter[y][mxs]=t; }
                for (x=0;x<=mxs;x+=dx2) { ter[0][x]=t; ter[mys][x]=t; }
                }
            // adjust randomness
            r>>=1; if (r<2) r=2; r2=r>>1;
            }
        // rescale to <h0,h1>
        xx=ter[0][0]; yy=xx;
        for (y=0;y<=mys;y++)
         for (x=0;x<=mxs;x++)
            {
            z=ter[y][x];
            if (xx>z)  xx=z;
            if (yy<z){ yy=z; xh1=x; yh1=y; }
            }
        for (y=0;y<=mys;y++)
         for (x=0;x<=mxs;x++)
          ter[y][x]=h0+(((ter[y][x]-xx)*(h1-h0))/(yy-xx));
        // test for correctness
        if (_island)
            {
            l=0;
            for (x=0;x<=mxs;x++) { if (ter[0][x]>h_water) l++; if (ter[mys][x]>h_water) l++; }
            for (y=0;y<=mys;y++) { if (ter[y][0]>h_water) l++; if (ter[y][mxs]>h_water) l++; }
            if (l>1+((mxs+mys)>>3)) continue;
            }
        break;
        }

    // [Surface]
    for (y=0;y<mys;y++)
     for (x=0;x<mxs;x++)
        {
        z=ter[y][x];
        // max slope [deg]
        a=atan2(ter[y][x+1]-z,d_pixel);
        b=atan2(ter[y+1][x]-z,d_pixel);
        if (a<b) a=b; a*=180.0/M_PI;

        c=_cover_none;
        if (z<=h_water) c=_cover_water;
        if (z>=h_snow ) c=_cover_snow;

        t=_terrain_dirt;
        if (z<=h_sand)  t=_terrain_sand;
        if (z>=h_rock)  t=_terrain_rock;
        if (a>=a_rock)  t=_terrain_rock;

        f=_flora_none;
        if (t==_terrain_dirt)
            {
            r=Random(100);
            if (r>10) f=_flora_grass;
            if (r>50)
                {
                if (z>h_evergreen) f=_flora_evergreen;
                else{
                    r=Random(h_evergreen);
                    if (r<=z) f=_flora_evergreen;
                    else      f=_flora_hardwood;
                    }
                }
            if (r<5) f=_flora_deadwood;
            }
        typ[y][x]=(c<<_cover_shift)|(t<<_terrain_shift)|(f<<_flora_shift);
        }

    // [Rivers]
    for (ix=10+Random(5),a=0.0,da=2.0*M_PI/float(ix);ix;ix--)
        {
        // random start around topest hill
        a+=da*(0.75+(0.50*Random()));
        for (l=0;l<10;l++)
            {
            b=Random(mxs>>3);
            x=xh1; x+=float(b*cos(a));
            y=yh1; y+=float(b*sin(a));
            if ((x<1)||(x>=mxs)) continue;
            if ((y<1)||(y>=mys)) continue;
            if (typ[y][x]&0x00F==_cover_water) continue;
            l=-1;
            break;
            } if (l>=0) continue; // safety check
        for (l=0,r2=0;;)
            {
            // stop on map edge
            if ((x<=0)||(x>=mxs-1)||(y<=0)||(y>=mys-1)) break;
            // decode generated surface
            r=typ[y][x];
            c=(r>>  _cover_shift)&  _cover_mask;
            t=(r>>_terrain_shift)&_terrain_mask;
            f=(r>>  _flora_shift)&  _flora_mask;
            // stop if reached sea
            if (c==_cover_water) break;
            // insert river dot radius = r2
            dx=x-r2; if (dx<0) dx=0; dx2=x+r2; if (dx2>=mxs) dx2=mxs-1;
            dy=y-r2; if (dy<0) dy=0; dy2=y+r2; if (dy2>=mys) dy2=mys-1;
            for (yy=dy;yy<=dy2;yy++)
             for (xx=dx;xx<=dx2;xx++)
              if (((xx-x)*(xx-x))+((yy-y)*(yy-y))<=r2*r2)
               if (((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)
                typ[yy][xx]=(typ[yy][xx]&0x00F)|(_terrain_temp<<_terrain_shift);
            // step to smalest elevation neighbor
            dx=x;   dy=y; z=h1; typ[y][x]=(typ[y][x]&0x00F)|(_terrain_water<<_terrain_shift); xx=x; yy=y;
            xx--; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            yy--; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            xx++; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            xx++; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            yy++; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            yy++; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            xx--; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            xx--; r=ter[yy][xx]; if ((z>=r)&&(((typ[yy][xx]>>_terrain_shift)&_terrain_mask)!=_terrain_water)) { z=r; dx=xx; dy=yy; }
            if ((dx==x)&&(dy==y))
                {
                // handle invalid path or need for a lake!!!
                if (dx>mxs>>1) dx++; else dx--;
                if (dy>mys>>1) dy++; else dy--;
                }
            x=dx; y=dy;
            // increase river volume with length
            l++; if (l>d_river_l*(r2+1)) { l=0; if (r2<d_river_w) r2++; }
            }
        // make merging of rivers possible
        for (y=0;y<=mys;y++)
         for (x=0;x<=mxs;x++)
          if (((typ[y][x]>>_terrain_shift)&_terrain_mask)==_terrain_water)
           typ[y][x]=(typ[y][x]&0x00F)|(_terrain_temp<<_terrain_shift);
        }
    for (y=0;y<=mys;y++)
     for (x=0;x<=mxs;x++)
      if (((typ[y][x]>>_terrain_shift)&_terrain_mask)==_terrain_temp)
       typ[y][x]=(typ[y][x]&0x00F)|(_terrain_water<<_terrain_shift);


    // [copy data] rewrite this part to suite your needs
    for (y=1;y<_ys;y++)
     for (x=1;x<_xs;x++)
        {
        float nx,ny,nz,x0,y0,z0,x1,y1,z1;
        // (nx,ny,nz) = surface normal
        nx=0.0;      ny=0.0; nz=ter[y][x];
        x0=-d_pixel; y0=0.0; z0=ter[y][x-1];
        x1=0.0; y1=-d_pixel; z1=ter[y-1][x];
        x0-=nx; x1-=nx;
        y0-=ny; y1-=ny;
        z0-=nz; z1-=nz;
        nx=(y0*z1)-(z0*y1);
        ny=(z0*x1)-(x0*z1);
        nz=(x0*y1)-(y0*x1);
        x0=1.0/sqrt((nx*nx)+(ny*ny)+(nz*nz));
        nx*=x0;
        ny*=x0;
        nz*=x0;
        // z = ambient light + normal shading
        nz=(+0.7*nx)+(-0.7*ny)+(+0.7*nz);
        if (nz<0.0) nz=0.0;
        nz=255.0*(0.2+(0.8*nz)); z=nz;
        // r = base color
        r=typ[y][x];
        c=(r>>  _cover_shift)&  _cover_mask;
        t=(r>>_terrain_shift)&_terrain_mask;
        f=(r>>  _flora_shift)&  _flora_mask;
               r=_terrain[t];
        if (c) r=  _cover[c];
        if (f){ if (c) r|=_flora[f]; else r=_flora[f]; };
        // sea color is depending on depth not surface normal
        if (c==_cover_water) z=256-((ter[y][x]<<7)/h0);
        // apply lighting z to color r
        yy=int(r>>16)&255; yy=(yy*z)>>8; if (yy>255) yy=255; r=(r&0x0000FFFF)|(yy<<16);
        yy=int(r>> 8)&255; yy=(yy*z)>>8; if (yy>255) yy=255; r=(r&0x00FF00FF)|(yy<< 8);
        yy=int(r    )&255; yy=(yy*z)>>8; if (yy>255) yy=255; r=(r&0x00FFFF00)|(yy    );
        // set pixel to target image
        pic.p[y][x].dd=r;
        }

    // free ter[][],typ[][]
    for (y=0;y<=mys;y++) delete[] ter[y]; delete[] ter; ter=NULL;
    for (y=0;y<=mys;y++) delete[] typ[y]; delete[] typ; typ=NULL;
    }
//---------------------------------------------------------------------------

यह कोड मेरा लिंक के उत्तर से कोड पर आधारित है, लेकिन अतिरिक्त सुविधाओं के साथ (नदियों में शामिल है)। मैं छवियों के लिए अपनी तस्वीर वर्ग का उपयोग करता हूं ताकि कुछ सदस्य हों:

  • पिक्सल में xs,ys आकार का आकार
  • p[y][x].dd पिक्सेल पर (x,y) स्थिति 32 बिट पूर्णांक प्रकार के रूप में है
  • clear(color) - पूरी छवि को साफ करता है
  • resize(xs,ys) - नए संकल्प पर छवि का आकार बदलता है
  • bmp - वीसीएल कैनवास पहुंच के साथ जीडीआई बिटमैप समझाया गया

आप इलाके की चिकनाई को बदलने के लिए डायमंड एंड स्क्वायर में adjust randomness को adjust randomness कर सकते हैं। इसके अलावा ऊंची सीमाएं और सीमाएं छेड़छाड़ की जा सकती हैं।

नदियों की तरह अधिक ब्रंचिंग हासिल करने के लिए समूहों में अधिक शुरू अंक बढ़ते हैं ताकि उन्हें एक या अधिक नदियों में समय में मिला दिया जाए।