首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Netlogo中随机地将一个正方形划分为更小的正方形

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

Stack Overflow用户
提问于 2017-12-14 05:08:38
回答 1查看 136关注 0票数 0

在Netlogo中有没有一种方法可以把一个矩形分成较小的、随机大小的矩形?如下图所示,有6个矩形,其中一个已细分,细分为黑色:

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

EN

回答 1

Stack Overflow用户

发布于 2017-12-16 04:35:16

我认为这是相当棘手的,特别是如果你想要特定的最小尺寸。也许可以尝试一下下面的代码,看看它是否能让你入门?它基本上接受一个矩形输入(可能是农场图),并生成一大堆重叠的矩形。随机位的问题是,你可以(按原样)得到比你的1/8更窄或更高的部分,因为你得到了重叠。使用计数器来增加或减少矩形的数量-更少意味着整个补丁可能不被细分,更多意味着更长的运行时间和潜在的更小的细分。

代码语言:javascript
运行
复制
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的一个补丁正方形,因此您必须按自己的喜好对它们进行排序。

要查看它是如何工作的,请将显示设置为连续并减慢速度。本质上,一只乌龟在一块没有id的地块上发芽,孵化出一个伙伴,在他们转向相同的方向并向前移动一段距离之前,这个伙伴走了一段距离。每个角面片的x和y坐标被存储在一个列表中,然后用来为它们定义的矩形分配一个id。

代码语言:javascript
运行
复制
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

输出如下所示:

其中红色以外的颜色表示具有不同ids的矩形。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47802136

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档