Desert Mountain Lake — An Introduction to Fill

In a recent update to turtleSpaces, we added the ability to create arbitrary shapes, using the beginfill and endfill primitives.

To create a shape, you simply declare beginfill, draw out its borders and then declare endfill. If the lines do not cross each other, then the shape should be created.

For example:

beginfill forward 50 right 90 forward 50 endfill

will create a triangle. But we already have plenty of ways to create triangles, right?

If you add right 60 forward 20 to just before endfill, you’ll understand. You can create whatever shape you want, you just need to make sure your lines don’t cross!

So what can we do with this? Let’s start with a simple example. We could create randomly-generated mountains. Generative art is becoming popular, so let’s see what all the fuss is about.

Okay, so we’re going to draw out the shape of the mountains by starting at the far left, then angling the turtle 30 to 60 degrees to the right.

penup setx -250 beginfill right 30 + random 30

Next we’ll move forward 50 turtle units plus a random number made up of 100 minus the turtle’s current Y position. This will keep us (mostly) from going off the top of the viewable area.

dountil xpos > 220 [
  right 30 + random 30
  forward 50 + random 100 - ypos

Then we’ll turn right between 70 and 110 degrees, for the downslope, and move forward the value of the current y (vertical) position. This will keep us from going below the centerline of the viewable area.

  right 70 + random 40
  forward ypos

Then we’ll return the turtle to the upright position, and then keep creating new mountains until we end up off the right side of the viewable area.

  setheading 0
]

Then we set the turtle’s y position to 0 and declare the endfill:

sety 0
endfill

So that’s not too bad, but we want more! (We always want more.) We’ve made the background blue (using setbackgroundcolor blue) which is going to be our lake, but maybe we want the sky to be a different color. So let’s add a quad before we start drawing the mountains.

This is pretty simple, we’re just going to set the fill color to red and then create the quad at the point we’re going to start drawing the mountains:

setx -250
setfillcolor red
quad 500 150
raise 1/5

Note that we need to raise the turtle a little bit so our sky and the mountains don’t ‘Z-fight’ with each other.

Okay so what about that cool reflection effect? How do we do that? Well, it’s actually pretty simple.

All we’re going to do is log the positions of the turtle as we create the mountains, then ‘replay’ her movements, but with the y position reversed.

To do that, we’re first going to create an empty list, using make.

make "points []
setx -250

Next we’re going to queue our positions into the list. We need to do this in two places in our mountain creation loop, at the peaks and the troughs.

dountil xpos > 220 [
  queue position "points
  rt 30 + random 30
  fd 50 + random 100 - ypos
  queue position "points
  ...
  sety 0 queue position "points
  ;we need to make sure to 'log' the final position

Once the mountains are drawn, we simply declare beginfill again, and use foreach and setposition to move the turtle to each point we logged, but we’re going to use the list primitive to change the y value from a positive to a negative.

setfillshade 5
beginfill
foreach "i :points [
  setposition (list first :i negative second :i third :i)
]
endfill

In the full example we use definecolor to make our brown color a little more blue, for creating the reflection.

The sun is the proverbial icing on the cake. We’re going to make the sun and its reflection using the pie primitive to make half a circle. We’ll generate a number between 80 and 119 and put it into a container, representing the sun’s size.

make "sun 80 + random 40

We’ll position the turtle either at the left-third, center or right-third of the screen:

setxc pick [-71 0 71]

We’ll create the sun:

setfillcolor yellow
pie 180 :sun

Then we’ll redefine the yellow color to make it a bit more blue and subdued.

definecolor yellow [50 50 20]

Finally we’ll turn 180 degrees, create the reflection, then turn back.

right 180
pie 180 :sun
right 180
lower 1/10

We place all of this before we create the quad that draws the red background. So we need to lower the turtle to ensure the sun and the background don’t z-fight.

Here is the full procedure listing:

TO desertmountainlake
  reset hideturtle penup
  setbackgroundcolor blue
  definecolor red [100 0 0]
  definecolor brown [50 31 15]
  ;redefine the colors
  
  setx pick [-71 0 71]
  make "sun 80 + random 40
  setfillcolor yellow pie 180 :sun
  definecolor 13 [50 50 20]
  right 180 pie 180 :sun right 180
  lower 1/10
  ;draw the sun
  
  make "points []
  setx -250
  setfc red quad 500 150
  ;create the red sky quad
  
  raise 2 / 10 setfc orange
  beginfill
  ;start drawing the mountains
  dountil xpos > 220 [
    queue position "points
    right 30 + random 30
    forward 50 + random 100 - ypos
    queue position "points
    rt 70 + random 40
    ;rt is short for right, lt left etc
    fd ypos setheading 0
    ;fd is short for forward
  ]
  sety 0 queue position "points
  ;we need to queue the final position
  endfill
  ;close the fill
  
  ;the reflection:
  setfc brown setfs 5 beginfill
  foreach "i :points [
    setposition (list first :i negative second :i third :i)
  ]
  endfill
  
END