CS21 Lab 7: OOP and Graphics

Due Saturday, March 19, by 11:59pm

Programming Tips

As you write programs, use good programming practices:

• Use a comment at the top of the file to describe the purpose of the program (see example).

• All programs should have a `main()` function (see example).

• Use variable names that describe the contents of the variables.

• Write your programs incrementally and test them as you go. This is really crucial to success: don’t write lots of code and then test it all at once! Write a little code, make sure it works, then add some more and test it again.

• Don’t assume that if your program passes the sample tests we provide that it is completely correct. Come up with your own test cases and verify that the program is producing the right output on them.

• Avoid writing any lines of code that exceed 80 columns.

• Always work in a terminal window that is 80 characters wide (resize it to be this wide)

• In `vim`, at the bottom left in the window, there is an indication of both the line and the column of the cursor.

Are your files in the correct place?

Make sure all programs are saved to your `cs21/labs/07` directory! Files outside that directory will not be graded.

```$update21$ cd ~/cs21/labs/07
$pwd /home/username/cs21/labs/07$ ls
Questions-07.txt
(should see your program files here)```

All functions should have a top-level comment! Please see our function example page if you are confused about writing function comments.

Are your files in the correct place?

Make sure all programs are saved to your `cs21/labs/07` directory! Files outside that directory will not be graded.

```$update21$ cd ~/cs21/labs/07
$pwd /home/username/cs21/labs/07$ ls
Questions-07.txt
(should see your program files here)```

Goals

• Create and manipulate multiple graphical objects.

• Use method syntax to perform actions on objects

• Write and use functions that have objects as parameters

• Use nested loops to process gridded data.

You are strongly encouraged to review in class examples and the Graphics Documentation for reference on Graphics classes and method syntax.

1. Field of Flowers

Figure 1. 4x4 grid of flowers

Write a program `flowers.py` that draws an $n \times n$ grid of flowers. Your program should prompt the user to enter an integer number of flowers $n$ in each row and then draw an $n \times n$ grid of flowers.

Your solution must include a helper function

``draw_flower(win, row, col)``

that draws a single flower at a particular row and column.

You may choose a different color scheme for your flower, or even have a different color for each flower, as long as there is an $n \times n$ grid of flowers. You can design a flower of your choosing, but your flower should consist of at four circles and at least two different colors.

You program must wait for the user to click the mouse on the graphics window before exiting.

```\$ python3 flowers.py
Enter number of white flowers across: 4
[window displays with middle image below]```
Figure 2. 1x1 grid of flower
Figure 3. 4x4 grid of flowers
Figure 4. 10x10 grid of flowers

1.1. Hints

• You should should create a square graphics window with the same width and height.

• Use the `setCoords(xll,yll,xur,yur)` method to set the coordinates of the graphics window you create regardless of the width and the height of the actual window. If you call `setCoords` after you know the value of $n$, calculating the coordinates of the flower geometry can be simplified.

• The `move` method can help position similar objects in different locations.

• Testing with $n=1$ should draw a single flower in the center of the screen.

• You can write a `make_flower` function that creates and returns a list of circle objects composing the flower. `draw_flower` should just need to call `make_flower` multiple times and move each flower to a new position in the grid.

The image below shows a horizontal $x$ and vertical $y$ scale for the $n=1$ image, when we use `setCoords(0,0,1,1)` to set the scale for the graphics window. This may help you design your initial `draw_flower` function. You will need to think about how to modify your code to work for larger values of $n$.

Figure 5. 1x1 grid of flowers annotated with scale when using `setCoords(0,0,1,1)`

Other flower examples are shown below

Figure 6. Example flower
Figure 7. Example flower

2. Trees

Figure 8. Spring Scene

Write a program `trees.py` that allows a user to interactively draw a spring scene consisting of multiple trees in bloom.

2.1. Initial setup

Figure 9. Initial Scene

You should start designing your program by creating a simple scene in a graphics window consisting of

1. A rectangular sky at the top

2. A rectangular ground at the bottom

3. A circular sun somewhere in the sky, preferably near the top of the window

Write a function `make_sun(win)` that creates the sun object in the graphics window and returns the circle object representing the sun. Additionally, write a function `make_ground(win)` that creates the ground and returns the rectangular object representing the ground. Write a main function that creates the primary graphics window, calls your two helper functions, and then repeatedly gets mouse clicks from the user until the user clicks inside the sun. When the user clicks inside the sun, the program should exit.

To determine if a click is inside the sun, compute the distance $d$ from the click to the center of the circle. If this distance is less than the radius of the sun, the point is inside the circle. To compute the distance between two points, $p_1$ and $p_2$, use the formula: $d=\sqrt{(p_1.\!x-p_2.\!x)^2+(p_1.\!y-p_2.\!y)^2}$. The notation $p_1.\!x$ means the $x$ coordinate of point $p_1$.

You must write a `distance` function to compute and return the distance between any two points.

You could also write an `inside` function that determines if a click point is inside a circle that uses your `distance` function.

A tree is define by three points:

• $p_1$: the center of the tree’s canopy.

• $p_2$: a point on the edge of the tree’s canopy

• $p_3$: a point located at the height of the base of the tree’s trunk.

The annotated image below shows the location of clicks for one sample tree. It wouldn’t be Swarthmore without a labeled tree somewhere.

Figure 10. Tree with point annotations.

Once the user has clicked on three points defining a single tree, you should draw a tree as follows:

1. Compute the distance $r$ between $p_1$ and $p_2$ using the distance formula above.

2. Create a circle with center $p_1$ and radius $r$ of a random fall color.

3. Compute the trunk size $t=\sqrt{r}$.

4. Compute the trunk base $b=p_3.\!y$.

5. Create a rectangular trunk of width $t$ centered around $p_1.\!x$ and extending vertically from $p_1.\!y$ to $b$.

6. Pick a random color for the trunk.

7. Draw the trunk first, then the circle.

Modify your program to draw a tree after every three clicks. You must write a `draw_tree` function of your own design. You may assume that if the first click is not in the sun, the next two clicks will form part of the tree and you do not need to do a sun check for $p_2$ and $p_3$. If the canopy of the tree covers the sun, your program should still exit if the user clicks where the sun was located previously on the next $p_1$ click.

Create a `Text` object that instructs what step is next. You can create a single `Text` object and use `setText` to change the current prompt as needed.

2.3. Example

The video below shows a sample of the program in use. For clarity, the individual mouse clicks are marked as black points until the tree is drawn. You do not need to implement this feature.

2.4. Hints

• Proceed incrementally. After the initial setup, modify the code to draw a circle of a fixed sized at the center of every mouse click. Then refine your solution to draw circles of different size using two clicks, $p_1$ and $p_2$. Next support the three click tree. Finally add random color support.

• The methods `getP1()` and `getP2()` return the opposite corners of a `Rectangle` object. This may be helpful for determining the height of the ground.

• It may be helpful to store point clicks temporarily in a list and then draw a tree once you have three clicks.

• You can create an empty list with the syntax `[]`

• You can use `.append()` to add a point to an existing list

• You can erase all the points in a list, resetting the list to empty using the `.clear()` method.

• Use `from math import sqrt` to get the `sqrt` function

• Use the `choice` function from the `random` library to get a random color. Here are some sample colors used:

• `leaf_colors = ["white", "violet", "SpringGreen1", "SpringGreen2", "yellow"]`

• `trunk_colors=["brown", "snow1", "SaddleBrown", "DarkGoldenRod4", "khaki4"]`

2.5. Optional extensions

These features are NOT required for full credit, but may be a fun extra challenge.

• If $b$ is located in the sky and not in the ground, modify $b$ to be the top of the ground.

• Modify your code so if the user clicks on the sun after clicking $p_1$ or $p_2$ (a partial tree), your program should still quit.

Each lab will have a short questionnaire at the end. Please edit the `Questions-07.txt` file in your `cs21/labs/07` directory and answer the questions in that file.

Once you’re done with that, you should run `handin21` again.

Submitting lab assignments

Remember to run `handin21` to turn in your lab files! You may run `handin21` as many times as you want. Each time it will turn in any new work. We recommend running `handin21` after you complete each program or after you complete significant work on any one program.

Logging out

When you’re done working in the lab, you should log out of the computer you’re using.

When Remotely logged in

When you are ssh’ed into the CS labs, first quit any applications you are running, like `vim`, then simply type `exit` at the prompt in your terminal window to disconnect.

When Physically logged in

When you are in a CS lab logged into a CS machine. First quit any applications you are running, like the browser and the terminal. Then click on the logout icon ( or ) and choose "log out".

If you plan to leave the lab for just a few minutes, you do not need to log out. It is, however, a good idea to lock your machine while you are gone. You can lock your screen by clicking on the lock icon. PLEASE do not leave a session locked for a long period of time. Power may go out, someone might reboot the machine, etc. You don’t want to lose any work!