2017-12-13 5 views
0

Netlogo에서 직사각형을 더 작고 임의의 크기의 사각형으로 나누는 방법이 있습니까? 검은 색 페인트 세분화 된 6 개 사각형, 하나 다음과 같은 이미지 및 세분화처럼 :Netlogo에서 사각형을 무작위로 작은 정사각형으로 나눕니다.

Subdivided farmland

이 질문은 내가 일반 사각형으로 구성 Netlogo에로드 농지의 SHP 파일을 가지고 있고, 원하기 때문에 도시 개발로 세분화되고 점령되는 방식을 시뮬레이션합니다. 세분의 크기는 총 제곱의 1/3에서 1/8 사이의 범위가 될 수 있습니다. 감사.

답변

1

매우 까다 롭습니다. 특히 특정 최소 크기를 원한다면 더욱 그렇습니다. 어쩌면 아래 코드를 사용하여 시작했는지 확인할 수 있습니다. 기본적으로 직사각형 입력 (잠재적으로 팜 플롯)을 취해 오버랩 사각형을 생성합니다. 랜덤 비트의 문제점은 겹치는 부분이 생기므로 1/8보다 좁거나 큰 섹션을 얻을 수 있다는 것입니다. 카운터를 사용하여 사각형 주위의 수를 늘리거나 줄이면 전체 패치를 세분화 할 수 없으므로 실행 시간이 길어질 수 있고 잠재적으로 더 작은 세분화가 가능합니다.

patches-own [ id ] 

to setup 
    ca 
    resize-world -50 50 -50 50 
    set-patch-size 4 
    ask patches [ set id -1 ] 
    ask rectangle -20 20 -40 40 [ 
    set pcolor red 
    ] 
    reset-ticks 
end 

to go 
    rectangle-sub -20 20 40 -40 
    tick 
end 

to rectangle-sub [ x0 x1 y0 y1 ] 

    ; Make sure the x0 x1/y0 y1 order is correct 
    let xp0 min (list x0 x1) 
    let xp1 max (list x0 x1) 
    let yp0 min (list y0 y1) 
    let yp1 max (list y0 y1) 

    ; Define the rectangle to subdivide 
    let main_rect rectangle xp0 xp1 yp0 yp1 

    ; Define width and height 
    let width xp1 - xp0 
    let height yp1 - yp0 
    let w3 round (width/3) 
    let w8 round (width/8) 
    let h3 round (height/3) 
    let h8 round (height/8) 

    ; Set a while loop to make mini rectangles, with 
    ; a counter to stop the loop after too many tries 
    let counter 0 
    while [ counter < 100 and any? main_rect with [id = -1 ] ] [ 
    let newx0 xp0 + (random width) 
    let newx1 newx0 + (ceiling width/(random 6 + 3)) 
    let newy0 yp0 + (random height) 
    let newy1 newy0 + (ceiling height/(random 6 + 3)) 

    ; define a sub rectangle 
    let newrect rectangle newx0 newx1 newy0 newy1 

    ; remove any patches from the sub rectangle that are not 
    ; also part of the main rectangle 
    set newrect newrect with [ member? self main_rect ] 
    if any? newrect [ 

     ; Make sure the dimensions aren't too small or big 
     let nwidth (max [pxcor] of newrect - min [pxcor] of newrect) 
     let nheight (max [pycor] of newrect - min [pycor] of newrect) 
     if nwidth < w3 and nwidth > w8 and nheight < h3 and nheight > h8 [ 

     ; Choose a random patch and assign its id to all others 
     ; in the same newrect patch-set 
     let groupid random 10000 
     ask newrect [ 
      set id groupid 
      set pcolor id/100 
     ] 
     ] 
    ] 
    set counter counter + 1 
    ] 
    print counter 

end 

to-report rectangle [ x0 x1 y0 y1 ] 
    ; reports a patch-set bounded by 
    ; the coordinate arguments passed 
    report patches with [ 
    pxcor > x0 and pxcor < x1 and 
    pycor > y0 and pycor < y1 
    ] 
end 

편집 : 내가 배 밖으로 여기에 조금 갈 수 OK-

하지만이 문제를 좋아한다. 여기에 거북이가 직사각형을 그리는 대체 솔루션이 있습니다. 즉, 중복이 없습니다. 또한 사각형은 외부 또는 이전에 id-d 사각형을 만들어야하므로 임의로 연결이 해제 된 사각형을 얻지 못합니다. 그러나 사각형 안에 ID가없는 1 패치 사각형을 남길 수 있으므로 원하는대로 정렬해야합니다.

어떻게 작동하는지 보려면 디스플레이를 연속으로두고 속도를 늦 춥니 다. 본질적으로, ID가없는 패치에 거북이가 나고, 같은 방향을 돌리고 앞으로 나아가고 약간의 거리를 이동하기 전에 어느 정도 거리를 이동하는 파트너가 부화합니다. 각 모퉁이 패치의 x와 y 좌표는 목록에 저장되고 정의 된 사각형에 ID를 할당하는 데 사용됩니다.

enter image description here

이 경우 빨간색이 아닌 다른 색상이 서로 다른 ID를 가진 사각형을 나타냅니다

patches-own [ id ] 

to setup 
    ca 
    resize-world -50 50 -50 50 
    set-patch-size 5 
    ask patches [ set id -1 ] 
    ask rectangle -20 20 -40 40 [ 
    set pcolor red 
    ] 
    reset-ticks 
end 

to go 
    turtle-define-rect -20 20 40 -40 
    tick 
end 


to turtle-define-rect [ x0 x1 y0 y1 ] 

    ; Make sure the x0 x1/y0 y1 order is correct 
    let xp0 min (list x0 x1) 
    let xp1 max (list x0 x1) 
    let yp0 min (list y0 y1) 
    let yp1 max (list y0 y1) 

    ; Define the rectangle to subdivide 
    let main_rect rectangle xp0 xp1 yp0 yp1 

    let xlist [] 
    let ylist [] 
    let possible_area one-of main_rect with [ 
    id = -1 and 
    any? neighbors4 with [id = -1] and 
    any? neighbors4 with [not member? self main_rect or id != -1] 
    ] 
    if possible_area != nobody [ 
    ask possible_area [ 
     let w random 5 + 5 
     let h random 10 + 10 
     sprout 1 [ 
     set color blue 
     set size 3 
     let start-patch patch-here 
     let id_temp [id] of patch-here 
     face one-of neighbors4 with [not member? self main_rect or id != -1] 
     rt 180 
     hatch 1 [ 
      create-link-with one-of other turtles-here 
      repeat w [ 
      if ([id] of patch-ahead 1 = -1) and ([ member? self main_rect] of patch-ahead 1) [ 
       fd 1 
      ] 
      ] 
     ] 
     set xlist lput xcor xlist 
     set ylist lput ycor ylist 
     ask link-neighbors [ 
      set xlist lput xcor xlist 
      set ylist lput ycor ylist 
     ] 
     let turn one-of [ 90 -90 ] 
     rt turn 
     ask link-neighbors [ 
      rt turn 
     ] 
     ask my-links [ 
      tie 
     ] 
     repeat h [ 
      if ( 
      ([id] of patch-ahead 1 = -1) and 
      ([ member? self main_rect] of patch-ahead 1) and 
      ([ [id] of patch-ahead 1 = -1 ] of link-neighbors = [true]) and 
      ([ [ member? self main_rect] of patch-ahead 1 ] of link-neighbors = [true]) 
     ) 
      [ 
      fd 1 
      ] 
     ] 
     set xlist lput xcor xlist 
     set ylist lput ycor ylist 
     ask link-neighbors [ 
      set xlist lput xcor xlist 
      set ylist lput ycor ylist 
     ] 
     ask link-neighbors [ die ] 
     die 
     ] 
    ] 
    let xt0 min xlist 
    let xt1 max xlist 
    let yt0 min ylist 
    let yt1 max ylist 
    let new_id random 10000 

    ask rectangle xt0 xt1 yt0 yt1 [ 
     set id new_id 
    ]  
    ] 

    ask main_rect with [ id != -1 ] [ 
    set pcolor id/100 
    ] 
end 

to-report rectangle [ x0 x1 y0 y1 ] 
    ; reports a patch-set bounded by 
    ; the coordinate arguments passed 
    report patches with [ 
    pxcor >= x0 and pxcor <= x1 and 
    pycor >= y0 and pycor <= y1 
    ] 
end 

출력과 같이 보입니다.

+0

루크, 시간 내 주셔서 감사합니다. 귀하의 답변은 실제로 도움이됩니다. 1/8은 단지 제안 일 뿐이며, 실제로 중요한 것은 직사각형이 겹치지 않아야한다는 것입니다. 실생활에서는 동일한 공간을 차지하는 두 개의 도시 개발을 의미합니다. 새로운 직사각형은 id = -1 인 패치에서만 형성 될 수 있다는 코드를 언급하면 ​​어떻게 할 수 있습니까? –

+0

@JavierSandoval - 안녕하세요, Javier- 알겠습니다. 개발을 모두 동시에 정의하는 것은 괜찮지 만 새로운 것을 개발하려는 경우는 아닙니다. 수정 된 답변에 대체 접근법을 추가했습니다. –

+0

다시 한번 감사합니다. 한 가지 더 : 하위 분할 수를 제어 할 수있는 방법이 있습니까? 실생활에서, 내가 공부하는 농지 계획은 더 적은 수로 세분화됩니다. –

관련 문제