2013-07-11 14 views
6

Przepraszam, jeśli ten tytuł nie jest zbyt opisowy. W każdym razie pracuję nad czymś, co dotyczy losowego generowania krajobrazów. Tworzyłem jeziora, ale ze względu na to, jak są one wytwarzane, często powodują proste krawędzie/zrzuty, które nie są pożądane. Próbuję go wygładzić (zaraz po zrobieniu jeziora, jeśli to możliwe), definiując maksymalną wielkość zmiany (aby wysokości gruntów nie mogły się różnić bardziej niż to), i aby to naprawić działkę, jeśli to się zmienia, i zakończyć, jeśli jest w porządku.Wygładzanie terenu wokół jezior

Problem:

Large dropoff

Moja próbował naprawić:

Attempted fix

Jak widać ... to nie działa. Przydarzyło mi się też, myślę, że zostałby złamany, gdyby musiał się przesunąć w dół, chociaż ta sprawa nie powinna się faktycznie pojawić, ponieważ jeziora tylko zatopiają krajobraz. W każdym razie, oto źródło mojej próby:

//smoothing land nearby 

      int maxVariation = 2; //similar to the max height variation when the land is generated 

      //going right 



      for (int xPos = rightBound + 1, previousHeight = 0; ; ++xPos) 
      { 
       if (previousHeight == 0) 
        for (; previousHeight < size.y; ++previousHeight) 
         if (grid[0][rightBound][previousHeight] != BlockColor::DIRT && grid[0][rightBound][previousHeight] != BlockColor::GRASS) 
         { 
          --previousHeight; 

          break; 
         } 


       for (int y = 0; y < size.y; ++y) 
        if (grid[0][xPos][y] == BlockColor::WATER) 
         goto done_smoothing_right; 

       int height; 

       for (height = 0; height < size.y; ++height) 
        if (grid[0][xPos][height] != BlockColor::DIRT && grid[0][xPos][height] != BlockColor::GRASS) 
        { 
         --height; 

         break; 
        } 

        int difference = std::abs(height - previousHeight); 

        previousHeight = height; 

        if (difference > maxVariation) 
        { 
         for (int j = 0; j < size.y; ++j) 
         { 
          int toMove = difference; 

          while (j + toMove >= size.y) 
           --toMove; 

          grid[0][xPos][j] = grid[0][xPos][j + toMove]; 
         } 
        } 
        else 
         goto done_smoothing_right; 


      } 

done_smoothing_right: 

      int tomakegotowork; 

Uwaga, że ​​jest to tylko prawa strona, ale lewo powinno być mniej więcej takie same. Jak mogę to zrobić poprawnie?

Dzięki, jeśli możesz pomóc.

EDYTOWANIE:

Nigdy nie rozwiązałem tego problemu. Zamiast tego stworzyłem funkcję rekursywną do mierzenia powietrza (z określonej wysokości), a jeśli kieszeń powietrzna (utworzona przez ląd) miała dość, by wypełnić wodą. Ma to korzystny wygląd ziemi, ponieważ nie jest zmieniony.

+0

rightBound jest jezioro w rightBound? Czy jeziora występują tylko na wysokości 0? –

+0

@MikeSaull Tak, rightBound jest x prawej wody. Jeziora występują nie tylko w punkcie 0, ale przy obecnej wysokości i głębokości jeziora wyglądają tak. –

Odpowiedz

1

To jest napisane w java, więc będziesz musiał przekonwertować go do C++, ale powinien dać ci podstawowy pomysł. Będzie działać tylko dla wygładzania w górę, a ja zrobiłem tylko prawą stronę jeziora, ale jest bardzo łatwa do modyfikacji po lewej stronie jeziora. Próbowałem dopasować to, co myślę, że funkcjonalność twojego kodu jest.

Nadzieja to pomaga ...

void smoothLakeRight(Lake lake){ 

    int x = lake.rightBound+1; 

    if(getGrassHeight(x)-lake.height>WorldConstants.MAX_LAKESIDE_VARIATION){ 
     //if the right bank is too high start smoothing 
     int y =lake.height+WorldConstants.MAX_LAKESIDE_VARIATION; 

     while(grid[0][x][y] == BlockColor.DIRT){ 
      fixGrass(x++, y++); 
     } 
    } 
} 

private int getGrassHeight(int xPos){ 

    int y = WorldConstants.LOWEST_GRASS; 

    while(grid[0][xPos][y++] != BlockColor.GRASS); 

    return y-1; 
} 

private void fixGrass(int xPos, int yPos){ 

    grid[0][xPos][yPos] = BlockColor.GRASS; 

    aboveAir(xPos,yPos); 
    belowDirt(xPos, yPos); 

} 

private void aboveAir(int xPos, int yPos) { 

    while(grid[0][xPos][++yPos]!=BlockColor.AIR){ 
     if(grid[0][xPos][yPos]==BlockColor.TREE){ 
      upRootTree(xPos, yPos); 
     }else{ 
      grid[0][xPos][yPos]=BlockColor.AIR; 
     } 
    } 
} 

private void upRootTree(int xPos, int yPos) { 

    while(grid[0][xPos][yPos]==BlockColor.TREE){//remove stump 
     grid[0][xPos][yPos++]=BlockColor.AIR; 
    } 

    //remove leaves 
    grid[0][xPos][yPos] = BlockColor.AIR; 
    grid[0][xPos+1][yPos] = BlockColor.AIR; 
    grid[0][xPos-1][yPos] = BlockColor.AIR; 
    grid[0][xPos+1][yPos-1] = BlockColor.AIR; 
    grid[0][xPos-1][yPos-1] = BlockColor.AIR; 
} 

private void belowDirt(int xPos, int yPos) { 

    while(grid[0][xPos][--yPos]!=BlockColor.DIRT){ 
     grid[0][xPos][yPos] = BlockColor.DIRT; 
    } 
}