Chapter 8 Sights and Sounds
---------------------------

Sights (Drawing)
----------------

Graphics package - included in myro

myCanvas = GraphWin()

creates a gray window (200 pixels height x 200 pixels wide)
labeled "Graphics Window"

myCanvas.close()

makes the window go away.

myCanvas = GraphWin("My Masterpiece",200,300)

creates a gray window labeled "My Masterpiece" of height 200 pixels
and width 300 pixels

myCanvas.setBackground("white")

sets the background color to white.

Other color names recognized are: "red", "blue", "gray",...
Google: Color Names to find out other color names.

To draw objects on the canvas window, you must first create
the object and then draw it.

Coordinate System of the canvas:

(0,0) top left corner
(width-1,height-1) at bottom right corner

x-coordinate increases as you go right
y-coordinate increases as you go down

Point Object:
-------------

p = Point(100,50)

creates a point object at (100,50)

p.draw(myCanvas)

draws the point object in the canvas.

Note: Object-oriented syntax...

Point objects has other functions:

x = p.getX()
y = p.getY()

returns x and y coordinates.

Line Object:
------------

L = Line(Point(0,0), Point(100,200))
L.draw(myCanvas)

start = L.getP1()
end = L.getP2()

start.getX()
0
start.getY()
0
end.getX()
100
end.getY()
200

for n in range(0,200,5):
  L = Line(Point(n,25), Point(100,100))
  L.draw(myCanvas)

See Picture on Page 191 (second picture) for output.

Do This:

####################################
from myro import *

def main():
  myCanvas = GraphWin()
  for n in range(0,200,5):
    L = Line(Point(n,25), Point(100,100))
    L.draw(myCanvas)
    wait(0.3)
    L.undraw()
####################################

See what happens.

Circle Object:
--------------

C = Circle(centerPoint,radius)
C.draw(myCanvas)

P = C.getCenter()

By default all objects are drawn in black. To introduce color:

C = Circle(Point(100,150), 30)
C.draw(myCanvas)
C.setOutline("red")
C.setFill("yellow")

To set width of circle outline (default is 1 pixel)

C.setWidth(5)

Text Object:
------------

myText = Text(Point(200,200), "Hello")
myText.setFace("arial") 
myText.setSize(16)
myText.setStyle('normal')
myText.draw(myCanvas)

Fonts supported:

'helvetica','arial','courier','times roman'

Sizes supported : between 5 and 72

Styles supported:

'bold','normal','italic', 'bold italic'

Image Object:
-------------

myPhoto = Image(Point(200,200), "raj.gif")
myPhoto.draw(myCanvas)

Only gif formats are supported.
To put a jpg photo, use the folowing commands:

pic = makePicture("raj.jpg")
pixmap = makePixmap(pic)
image = Image(Point(200,200),pixmap)
image.draw(myCanvas)

Colors:
-------

RGB Spectrum (0-255 each)
(255,255,255) = white
(0,0,0) = black
(255,0,0) = pure red
...

myColor = color_rgb(255,175,175)
myCanvas.setBackground(myColor)

creates a color object (pink!) and sets the background of the canvas.

Program to display a bunch of random circles:
---------------------------------------------

##################
# Program to draw a bunch of
# random colored circles
from myro import *
from random import *

def makeCircle(x, y, r):
    # creates a Circle centered at point (x, y) of radius r
    return Circle(Point(x, y), r)

def makeColor():
    # creates a new color using random RGB values
    red = randrange(0, 256)
    green = randrange(0, 256)
    blue = randrange(0, 256)
    return color_rgb(red, green,blue)

def main():
    # Create and display a
    # graphics window
    width = 500
    height = 500
    myCanvas = GraphWin('Circles',width,height)
    myCanvas.setBackground("white")
    # draw a bunch of random
    # circles with random
    # colors.
    N = 500
    for i in range(N):
        # pick random center
        # point and radius
        # in the window
        x = randrange(0,width)
        y = randrange(0,height)
        r = randrange(5, 25)
        c = makeCircle(x, y, r)
        # select a random color
        c.setFill(makeColor())
        c.draw(myCanvas)

main()
############################

Notice the two functions. 

makeCircle(x,y,r)
makeColor()

One has parameters and the other no parameters.
If we decide to write makeCircle without parameters:

def makeCircle():
  x = randRange(0,width)
  y = randRange(0,height)
  r = randRange(5,25)
  return Circle(Point(x,y),r)

This could cause a problem! The variables width and height
are defined inside main() and will not be available in this
function! 

General "Scope" rules:

1. Variables defined within one function (called local variables)
are not available to other functions (unless we send them as parameters)

2. Variables defined outside functions (called global variables)
are available to all functions defined AFTER them.

So, we could have defined 

  width = 500
  height = 500

before the makeCircle() function and this would have made them
available to makeCircle() without parameters. 

Moving Objects
--------------

c.move(10,5)

moves the object c right by 10 pixels and down by 5 pixels

Animation Program:
-----------------

##############
# Moving circle; Animate a circle...
from myro import *
from random import *

def main():
    # create and draw the graphics window
    w = GraphWin("Moving Circle", 500, 500)
    w.setBackground("white")
    
    # Create a red circle
    c = Circle(Point(250, 250), 50)
    c.setFill("red")
    c.draw(w)
    
    # Do a simple animation for 200 steps
    for i in range(200):
        c.move(randrange(-4, 5), randrange(-4, 5))
        wait(0.2)

main()
##############

comment the wait(0.2) statement and see what happens!
Too fast!

Another Animation Program:
--------------------------

#################
# Moving circle; Animate a circle...
from myro import *
from random import *

def main():
    # create and draw the graphics window
    winWidth = winHeight = 500
    w = GraphWin("Bouncing Circle", winWidth, winHeight)
    w.setBackground("white")

    # Create a red circle
    radius = 25
    c = Circle(Point(53, 250), radius)
    c.setFill("red")
    c.draw(w)

    # Animate it
    dx = dy = 3
    while timeRemaining(15):
        # move the circle
        c.move(dx, dy)

        # make sure it is within bounds
        center = c.getCenter()
        cx = center.getX()
        cy = center.getY()
        
        if (cx+radius >= winWidth) or (cx-radius <= 0):
            dx = -dx
        if (cy+radius >= winHeight) or (cy-radius <= 0):
            dy = -dy
            
        wait(0.01)

main()
#################

Add computer.beep(0.005, 440)
after changing directions whn hitting the wall!