2014-09-03 8 views
1

'130 줄의 현실적인 지형'처리 포트에서 발견 된 코드부터 시작하여 this article에있는 것과 같은 효과를 만들고 싶습니다. 코드를 수정하여 3D 지형보다는 처리 중 회색조 높이 맵만 생성합니다. 그러나 내 코드는 island heightmaps를 생성하지 않으며 here과 같이 특이한 사각형 패턴을 남깁니다. 다음과 같이섬을 생성하기위한 중간 지점 변위 구현으로 원하는 패턴이 생성되지 않습니까?

내 코드는 다음과 같습니다 어떤 도움

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); 
    } 
} 

감사합니다!

답변

1

먼저 16x16 블록으로 지형을 분해합니다. 결과물에서 이러한 경계선이 잘 보입니다. 왜 그런가요? 경계에서의 값이 각 블록 내의 값보다 훨씬 다르기 때문에 글쎄요.

블록 간의 차이점은 초기 generate 값에 의해 결정되며, 블록과의 차이는 divide입니다. generate 이하의 변형을 divide에 추가해야합니다.

그럼에도 불구하고 모든 블록이 생성 된 후 전체 이미지에 스무딩 연산자를 적용하는 것이 좋습니다. 이렇게하면 거칠기가 약간 줄어들지 만 특정 테두리 (특히 인간의 눈에 대한 가시성)가 더 감소합니다. 통계적 테스트를 통해 축 정렬 프로세스로 이미지가 생성되었음을 입증 할 수 있습니다.

+0

비트, 고마워! – Zarpar