根据物理特征划分区域
Divide regions accordingly to physical features
我正在做一个较小的项目,但遇到了一个问题,我不确定是否可以在 NetLogo 中解决它,但我想试试 Whosebug!
我得到了一个模型,它把世界分成不同的部分,随机添加物理特征(比如河流)。如果一个特征穿过整个区域,我希望它将区域分开并分成两个区域。例如,在下图中,我想根据物理特征(黑色)将紫色区域分成两个独特的区域。
我用来生成上面图片的代码,可以在下面找到。
to setup
ca
;Setting world.
resize-world 0 19 0 19
;Creating regions.
let x 5
let y 5
let col 45
while [y <= max-pycor + 1][
while [x <= max-pxcor + 1 ][
ask patches with [pxcor < x and pxcor >= x - 5 and pycor < y and pycor >= y - 5][
set pcolor col
]
set x x + 5
set col col + 10
]
set x 5
set y y + 5
]
;Generating physical features.
ask n-of 5 patches[ sprout 1[
set pcolor black]
]
let i 0
while [ i < (max-pycor * 2 )][
ask turtles [
fd 1
set pcolor black
ifelse (random 20 <= 1)
[
rt one-of [-90 0 90]
forward 1
]
[
fd 1
set pcolor black
fd 1
set pcolor black
]
set pcolor black
set i i + 1]
]
ask turtles [die]
end
我处理这个问题的策略是意识到我们真正需要做的就是 "flood" 按颜色划分出一个补丁并标记所有找到的相邻补丁,然后对任何未标记的非黑色重复补丁直到全部完成。
NetLogo 没有 "flood" 命令来获取与符合条件的补丁相邻的所有补丁,因此我们自己制作了一个特殊的报告器来处理它,patches-adjacent
。然后很容易让那些 patches-adjacent
将他们的 region
设置为当前选择的区域。
我不喜欢这段代码,它有点挑剔,如果调整不当很容易出现无限循环,但它应该可以工作。我敢打赌有一种我目前没有想到的更简洁的方法。
; add a variable to track the different regions
; the default value will be `0` for each patch when `clear-all` is called
patches-own [ region ]
to set-regions
let current-region 1
; only act on non-black patches that haven't yet been assigned a region
let untagged patches with [ region = 0 and pcolor != black ]
while [any? untagged] [
ask one-of untagged [
ask patches-adjacent [
set region current-region
]
]
; update the region and the untagged patches we have left to process
set current-region current-region + 1
set untagged patches with [ region = 0 and pcolor != black ]
]
; this is just to get a view of the regions to quickly see if our code worked, it can be removed
ask patches [ set plabel region ]
end
to-report patches-adjacent
report patches-adjacent-ex (patch-set self) pcolor
end
to-report patches-adjacent-ex [found pc]
let newly-found neighbors4 with [ (not member? self found) and pcolor = pc and region = 0 and pcolor != black ]
set found (patch-set found newly-found)
ask newly-found [
; use recursion to find the patches adjacent to each newly-found one
; relying on updating the `found` agentset as we go to avoid duplicates
; or looping forwarder
set found (patches-adjacent-ex found pc)
]
report found
end
我使用 NetLogo 模型库中的 Patch Clusters 模型解决了这个问题。
我正在做一个较小的项目,但遇到了一个问题,我不确定是否可以在 NetLogo 中解决它,但我想试试 Whosebug!
我得到了一个模型,它把世界分成不同的部分,随机添加物理特征(比如河流)。如果一个特征穿过整个区域,我希望它将区域分开并分成两个区域。例如,在下图中,我想根据物理特征(黑色)将紫色区域分成两个独特的区域。
我用来生成上面图片的代码,可以在下面找到。
to setup
ca
;Setting world.
resize-world 0 19 0 19
;Creating regions.
let x 5
let y 5
let col 45
while [y <= max-pycor + 1][
while [x <= max-pxcor + 1 ][
ask patches with [pxcor < x and pxcor >= x - 5 and pycor < y and pycor >= y - 5][
set pcolor col
]
set x x + 5
set col col + 10
]
set x 5
set y y + 5
]
;Generating physical features.
ask n-of 5 patches[ sprout 1[
set pcolor black]
]
let i 0
while [ i < (max-pycor * 2 )][
ask turtles [
fd 1
set pcolor black
ifelse (random 20 <= 1)
[
rt one-of [-90 0 90]
forward 1
]
[
fd 1
set pcolor black
fd 1
set pcolor black
]
set pcolor black
set i i + 1]
]
ask turtles [die]
end
我处理这个问题的策略是意识到我们真正需要做的就是 "flood" 按颜色划分出一个补丁并标记所有找到的相邻补丁,然后对任何未标记的非黑色重复补丁直到全部完成。
NetLogo 没有 "flood" 命令来获取与符合条件的补丁相邻的所有补丁,因此我们自己制作了一个特殊的报告器来处理它,patches-adjacent
。然后很容易让那些 patches-adjacent
将他们的 region
设置为当前选择的区域。
我不喜欢这段代码,它有点挑剔,如果调整不当很容易出现无限循环,但它应该可以工作。我敢打赌有一种我目前没有想到的更简洁的方法。
; add a variable to track the different regions
; the default value will be `0` for each patch when `clear-all` is called
patches-own [ region ]
to set-regions
let current-region 1
; only act on non-black patches that haven't yet been assigned a region
let untagged patches with [ region = 0 and pcolor != black ]
while [any? untagged] [
ask one-of untagged [
ask patches-adjacent [
set region current-region
]
]
; update the region and the untagged patches we have left to process
set current-region current-region + 1
set untagged patches with [ region = 0 and pcolor != black ]
]
; this is just to get a view of the regions to quickly see if our code worked, it can be removed
ask patches [ set plabel region ]
end
to-report patches-adjacent
report patches-adjacent-ex (patch-set self) pcolor
end
to-report patches-adjacent-ex [found pc]
let newly-found neighbors4 with [ (not member? self found) and pcolor = pc and region = 0 and pcolor != black ]
set found (patch-set found newly-found)
ask newly-found [
; use recursion to find the patches adjacent to each newly-found one
; relying on updating the `found` agentset as we go to avoid duplicates
; or looping forwarder
set found (patches-adjacent-ex found pc)
]
report found
end
我使用 NetLogo 模型库中的 Patch Clusters 模型解决了这个问题。