user2359494
user2359494

Reputation: 733

Creating a random shape (blob) of a given area in NetLogo

Is it possible to create random shapes (see below for example) of a given area in NetLogo?

enter image description here

Upvotes: 6

Views: 3137

Answers (3)

Bryan Head
Bryan Head

Reputation: 12580

I found a really simple approach that produces pretty nice results.

Create a turtle. The turtle performs a random walk. After each step, they set the uncolored patch closest to them to the desired color. The turtle does this a number of times equal to the desired area.

Here's the code:

to make-blob [ area ]
  let blob-maker nobody
  crt 1 [ set blob-maker self ]
  repeat area [
    ask blob-maker [
      ask min-one-of patches with [ pcolor = black ] [ distance myself ] [ set pcolor blue ]
      rt random 360
      fd 1
    ]
  ]
  ask blob-maker [ die ]
end

This naturally produces nicely curved blobs.

Making the turtle's step size smaller makes the blob more circle-y. Making it bigger results in thinner, more sporadic blobs (though you run the risk of getting disconnected patches).

Edit:

I noticed that my answer runs quite slowly when you have a gigantic number of patches. Here's a much faster version:

to make-blob [ area x y ]
  let blob-maker nobody
  crt 1 [ set blob-maker self setxy x y ]
  let border patch-set [ patch-here ] of blob-maker
  repeat area [
    ask blob-maker [
      ask min-one-of border [ distance myself ] [
        set pcolor green
        set border (patch-set border neighbors4) with [ pcolor = black ]
      ]
      rt random 360
      fd .8
    ]
  ]
  ask blob-maker [ die ]
end

Upvotes: 4

Frank Duncan
Frank Duncan

Reputation: 358

A first stab at Seth's suggestion #1. It creates a neat visual too!

patches-own [ height ]

to blobbify
  clear-all
  repeat (ceiling 2 * (ln (world-height * world-width))) [
    ask patch (round (random (world-width / 2)) - world-width / 4)
              (round (random (world-height / 2)) - world-height / 4)
              [ set height world-width * world-height ] ]
  while [ count patches with [ height > 1 ] < (world-width * world-height / 4)] 
        [ diffuse height 1
          ask patches with [ height > 0 ] [ set pcolor height ]
        ]
   ask patches with [ height > 1 ] [ set pcolor white ]
end

Upvotes: 4

Seth Tisue
Seth Tisue

Reputation: 30453

Generating random blobs is a hard problem with no obvious solution. Fixing the area of the blob makes it even harder.

You'll need to pick an approach, then try to figure out how to express that approach in NetLogo code.

As for what approach to pick, I imagine there's literature on this if you search. But just off the top of my head, I have three ideas:

  • Scatter random points around the world, use diffuse to make a smooth landscape around these peaks. (See the Diffusion Graphics model, in the Art section of NetLogo's Models Library, for code for this; you'll want to turn world wrapping off, though.) Then select only those patches where the "elevation" exceeds some threshold. To get the desired area, vary the threshold until the target is reached.

  • Draw a curve around the center point using polar coordinates, where theta goes from 0 to 360 and 4 varies randomly. You'll need a way to get smooth random variation in the radius, perhaps by generating random numbers and then applying a smoothing function to them. In order to force the blob to have the desired area, first generate the whole curve, then scale it as needed. You'll need some trick to avoid a discontinuity where theta = 0, perhaps by using a smoothing function that wraps.

  • Generate a random polygon by scattering points around the world, then discarding some or all points in the middle. (You could take the convex hull, but then you'll always get a convex shape, which might not be "blobby" enough for you. So you might want to something like like generating n random points and then keeping the m points that are farthest from the center, without regard to convexity.) Once you've got the random polygon, apply some smoothing function to turn it into a curvy blob. Then scale the whole thing as necessary to get the desired area.

Upvotes: 2

Related Questions