1

この記事のような効果を作りたいと思ったのは、「130 行のリアルな地形」の処理ポートにあるコードから始めました。コードを修正して、Processing で 3D 地形ではなくグレー スケールの高さマップのみを生成するようにしました。ただし、私のコードは島の高さマップを生成せず、ここに示されているように、異常な正方形のパターンも残します

私のコードは次のとおりです。

int size = 512;

Terrain t;

float rough = 0.7;
void setup() {

  t = new Terrain(8, size);
  doit();
}

void doit() {

  t.generate(rough);
  size(513, 513);
  loadPixels();
  for (int a=0;a<t.tMap.length;a++) {
    float val = ((t.tMap[a]+24)/48)*255;
    pixels[a] = color(floor(val));
  }
  updatePixels();
}

void mousePressed() {
  doit();
}

class Terrain {
  public final int tSize, tMax;
  public float[] tMap;
  public float tRoughness;

  Terrain(int detail, int size) {
    tSize  = size+1;
    tMax = tSize-1; 
    tMap = new float[tSize*tSize];
  }

  private float getp(int x, int y) {
    if (x < 0) x= tMax + x;
    if (x > tMax) x= x % tMax;
    if (y < 0) y= tMax + y;
    if (y > tMax) y= y % tMax;

    return tMap[x + tSize * y];
  }

  private void setp(int x, int y, float val) {

    tMap[x + tSize * y] = val;
  }

  public void generate(float roughness) {
    tRoughness = roughness;  
    //set edges and corners 0
    for (int x=0;x<tSize;x++) {
      setp(x, 0, 0);
      setp(x, tMax, 0);
    }
    for (int y=0;y<tSize;y++) {
      setp(y, 0, 0);
      setp(y, tMax, 0);
    }
    //seed random numbers every 16
    for (int x=0;x<tSize;x+=16) {
      for (int y=0;y<tSize;y+=16) {
        setp(x, y, random(-(roughness*16), roughness*16));
      }
    }
    //divide each 16x16 square
    for (int x=0;x<tSize;x+=16) {
      for (int y=0;y<tSize;y+=16) {
        divide(16, x, y);
      }
    }
  }

  private void divide(int size, int smallestX, int smallestY) {
    int x, y, half = size/2;
    float scale = tRoughness * size;
    if (half < 1) return;

    for (y = smallestY + half; y < tMax; y += size) {
      for (x = smallestX + half; x < tMax; x += size) {
        square(x, y, half, random(-scale, scale));
      }
    }
    for (y = smallestY; y <= tMax; y += half) {
      for (x = (y + half + smallestY) % size; x <= tMax; x += size) {
        diamond(x, y, half, random(-scale, scale));
      }
    }
    divide(size/2, smallestX, smallestY);
  }

  private float average(float[] values) {
    int valid = 0;
    float total = 0;
    for (int i=0; i<values.length; i++) {
      if (values[i] != -1) {
        valid++;
        total += values[i];
      }
    }
    return valid == 0 ? 0 : total / valid;
  }

  private void square(int x, int y, int size, float offset) {
    float ave = average(new float[] {
      getp(x - size, y - size), // upper left
      getp(x + size, y - size), // upper right
      getp(x + size, y + size), // lower right
      getp(x - size, y + size)  // lower left
    }
    );
    setp(x, y, ave + offset);
  }

  private void diamond(int x, int y, int size, float offset) {
    float ave = average(new float[] {
      getp(x, y - size), // top
      getp(x + size, y), // right
      getp(x, y + size), // bottom
      getp(x - size, y)  // left
    }
    );
    setp(x, y, ave + offset);
  }
}

助けてくれてありがとう!

4

1 に答える 1

1

最初に地形を 16x16 ブロックに分割します。出力では、これらの境界線がはっきりと見えます。何故ですか?境界の値は、各ブロック内の値の違いよりもはるかに異なるためです。

ブロック間の違いは初期generate値によって決定され、ブロックとの違いは によって引き起こされdivideます。generateのバリエーションを増やすか減らす必要がありますdivide

それでも、すべてのブロックが生成された後、画像全体に平滑化演算子を適用する価値があるかもしれません。これにより、粗さが少し減少しますが、特定の境界線の可視性がさらに低下します (特に人間の目には。統計テストでは、画像が軸合わせプロセスによって生成されたことを証明する可能性が高くなります)。

于 2014-09-03T08:40:22.207 に答える