Drawing mode
More squares and a bit of Forth
With the previous tutorial you didn't really use any of the concepts seen during the global Forth introduction of this documentation. With this section you will start to see how to combine the simple drawing technics we just saw with some classic Forth words and usage.
building on top of small ideas
One of the main aspect of Forth is the way you can easily construct complex construction based on simple systems. This is achieved by simply adding in the dictionnary your own words and their definition.
First of all let's initialize PF just like we did before: with an OpenGl 2D drawing environment.
load-opengl # load the OpenGl PF plugin 320 240 display # initialize a 384x288 window 2d # set the environment for 2D drawing # start the drawing system
Say you want to render a square at a random position. You would normally do that:
clearscreen 1.3 rand # generate a random float number between 0 and 1.3 0.65 - # substract 0.65 from the result transx # set the translation on x with the result 1. rand 0.5 - transy # the same for the y translation 0.1 square # we finally draw the square
Instead of going through all this list we can just define a new word that will be interpreted as this list of orders generating the x and y position. Let's call this word 'random-position'.
: random-position 1.3 rand 0.65 - transx 1. rand 0.5 - transy ;
Now generating a new small square at a random position on the screen is just a matter of writing:
clearscreen random-position 0.1 square
If you don't clear the screen before calling a new random square, you will be able to draw on top of the previous buffer and then keep visible what has already been drawn. There is a catch though. Try to pass this line a couple of times:
random-position 0.1 square
What happens ? You are able to draw a couple of squares and then nothing seems to work anymore. That's normal if you remember what we saw in the previous tutorial. n transx and n transy combos define a translation from the previous coordinate on the x or y axis for a n value. This is a relative translation of the element and not an absolute positioning.
As a consequence in our random-position word, we keep on moving the square in a random direction from its current position. Eventually the square gets moved out of the screen into the buffer limbo.
To make a proper random-position word we would need to store the element's position before moving it and then call it again once the translation has occured.
In PF there is no such thing as a position parameter, but you can access the world geometry, which defines all the transformations of your environment, at any time. You can save this state in a matrix with m-push and then call it back later with m-pop.
clearscreen # we clear the screen and reinitialize the environment m-push # we store the world transformations random-position 0.1 square # we spawn a square with random position m-pop # we call back the original wolrd transformations
now you can type a few time the following line until you fill your screen or get bored.
m-push random-position 0.1 square m-pop
defining more words
Obviously we can create a few more words to enhance our vocabulary:
: random-grey 1. rand dup dup rgb ; : random-size 0.25 rand ;
Note: random-grey generates a float between 0 and 1 then duplicate the result 2 times in order to feed 3 identical values to rgb. Read again the Forth introduction for more info on dup and the previous tutorial for simple examples using rgb.
... and a another that control the rotation using the "rot" family of words (rotx, roty and rotz)
: random-rotation 360. rand rotz ;
Finally, you can now combine these new words to spawn at once a square of a random size, position and grey value.
m-push random-position random-rotation random-grey random-size square m-pop
As you start to understand the advantage of Forth lies in the way you can quickly define small efficient rules to describe more complex process. That's why we should not stop here but instead use this process as a definition for a new word, grey-square, that once defined can be called again and again for endless entertainment.
: grey-square m-push random-position random-rotation random-grey random-size square m-pop ; grey-square grey-square grey-square grey-square
A few <up> <enter> later and some blisters on your fingers, you are certainly wondering about how you could fill the screen more efficiently. Here again some very basic concepts will be used. The same way we have used the for next loop during the introduction to Forth, you are going to apply this in a new word. The word will be defined as a programmable loop which can repeat grey-square.
: squarish for grey-square next ; 10 squarish 100 squarish 1000 squarish
Attachments
- random-position.png (1.5 kB) - added by aym3ric 4 years ago.
- squarish.png (10.9 kB) - added by aym3ric 4 years ago.
