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