What is the algorithm for drawing this picture? How do we create the crescent moon using just Circle objects?
create graphics window
set background to black
for loop to create stars
pick random x from 0->width
pick random y from 0->height
create Point(x,y)
draw Point, color it white
create and draw a white circle
clone circle, draw it, move it a little, color it black
We did not talk about the clone()
method last time. It is very
useful for creating lots of similar objects, like eyes for a face.
Most graphics objects (e.g., Points, Circles, Rectangles, Text) have
a clone
method that works like this:
p = Point(100,200)
radius = 50
c = Circle(p, radius)
c.setFill("red")
c2 = c.clone()
So c2
is an exact copy of c
, but it is not drawn on the screen yet.
Let's create the program for this next picture together.
First, create the sky, grass, and sun:
from graphics import *
def main():
width = 600
height = 400
gw = GraphWin("pretty forest picture...", width, height)
# sky
gw.setBackground("lightblue")
# grass
grassheight = 0.75*height
p1 = Point(0,grassheight)
p2 = Point(width,height)
grass = Rectangle(p1,p2)
grass.setFill("green")
grass.setOutline("green")
grass.draw(gw)
# sun
sun = Circle(Point(width*.15,height*.1), width*.05)
sun.setFill("yellow")
sun.setOutline("yellow")
sun.draw(gw)
# wait for user input before ending program/closing window
click = gw.getMouse()
Notice that I use variables for width
and height
, and all other variables,
like grassheight
and the sun's radius, depend on them. If I go back and
change width and/or height, the rest of my program should adjust accordingly.
Now let's add a drawTree(grassheight,gw)
call to the above, to draw
just one tree in the window gw
at the given grassheight
.
The function definition with pseudo code looks like this:
def drawTree(grassheight, window):
get width of window
pick random x from 0->width
create a Point object at x,grassheight
make other Point objects for the trunk (a Rectangle)
and the tree top (a Circle?)
pick a random shade of brown for the trunk
pick a random shade of green for the tree top
draw the trunk and the top in the window
It may be helpful to sketch the tree on paper, to see where the points
for the trunk and the top should be, relative to the starting point
at x,grassheight
. You might also want to use randrange()
to pick the
tree width/height, so not all trees are the exact same size (later, we
will call this drawTree()
function from main
, and we will want
trees with different heights and widths).
Here's one possible algorithm for creating the trunk, given an initial
point at x,grassheight
:
pt = Point(x, grassheight)
pick random tree width
treeheight = 2*treewidth
p1 = pt.clone()
move p1 half a treewidth left
p2 = pt.clone()
move p2 half a treewidth right, and -treeheight up
create trunk using Rectangle(p1,p2)
Almost any color can be made by mixing various amounts of red, green, and
blue light. The color_rgb(r,g,b)
function allows you to create colors this way,
varying the amounts of each color from none (0) to full-on (255). Here is some code to create
random colors:
r = randrange(0,256)
g = randrange(0,256)
b = randrange(0,256)
mycolor = color_rgb(r,g,b)
c = Circle(...)
c.setFill(mycolor)
How would you change the above to get a random greenish color?
Below is the full drawTree()
function. Make sure you understand how
it works, and how it should be called from main()
.
def drawTree(grassheight, window):
"""create and draw a tree at given height, in window"""
width = window.getWidth()
x = randrange(0, width)
pt = Point(x, grassheight)
treewidth = randrange(width*.05, width*.15)
p1 = pt.clone()
p1.move(-treewidth/2, 0)
treeheight = 2*treewidth
p2 = pt.clone()
p2.move(treewidth/2,-treeheight)
trunk = Rectangle(p1, p2)
trunk.setFill("brown")
trunk.setOutline("brown")
trunk.draw(window)
p2.move(-treewidth/2,0) # center of tree top
radius = treewidth*.9
treetop = Circle(p2, radius)
r = randrange(0,100)
g = randrange(200,256)
b = randrange(0,80)
treecolor = color_rgb(r,g,b)
treetop.setFill(treecolor)
treetop.setOutline(treecolor)
treetop.draw(window)