在Netlogo中随机将一个正方形划分为较小的正方形

时间:2017-12-13 21:08:38

标签: gis netlogo

有没有办法在Netlogo中将矩形划分为更小的随机尺寸矩形?如下图所示,有6个矩形,一个已经细分,细分为黑色:

Subdivided farmland

这个问题是因为我有一个由常规矩形组成的Netlogo中加载的农田shp文件,并希望模拟它们如何被城市发展细分和占用。细分的大小可以是总方的1/3到1/8之间的范围。感谢。

1 个答案:

答案 0 :(得分: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

<强>编辑:

好的 - 我可能在这里有点过分,但我喜欢这个问题。这是一种替代解决方案,让海龟绘制矩形 - 这样就没有重叠。此外,矩形必须构建外部或以前的id-d矩形,因此您不会获得随机断开的矩形。但是,它可以在矩形中留下没有id的单补丁方块,因此您必须根据需要对它们进行排序。

要了解它的工作原理,请将显示屏连续放下并慢慢放下。从本质上讲,一只乌龟在一个没有身份的补丁上发芽,孵出一个伙伴,他们在转向同一个方向并向前移动并移动一段距离之前会移走一段距离。每个角补丁的x和y坐标存储在一个列表中,然后用于为他们定义的矩形指定一个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

输出类似于:

enter image description here

除红色以外的颜色表示具有不同ID的矩形。