![]() |
Problem Set 3
|
In this problem set, you will practice reading, writing, and understanding methods. Think carefully about what patterns should be abstracted into methods and which patterns should be named as variables.
To get the code for this assignment, connect to the cs
server via
Fetch or WinSCP. Use the cs111d
account and the password given
in class and download the ps03_programs folder.
You must turn in both a hardcopy and a softcopy. For general guidelines on problem set submission, including how to submit a softcopy and how to check if you softcopy submission was successful, click here. Please make sure to keep a copy of your work, either on an external storage device (like a USB drive), or in your private directory (or, to play it safe, both).
Your hardcopy packet should consist of:
KnitWorld.java
file from Task 1;QuiltWorld.java
file from Task 2.Staple these together, and submit the packet at the start of class on the due date. Don't forget to put one of the instructors' stickers on the cover page!
Save the modified KnitWorld.java
and
QuiltWorld.java
files in the ps03_programs
folder. Submit the entire ps03_programs
folder to your
drop folder on the CS111 server.
To demonstrate some of the capabilities of PictureWorld
, we have
included the file MyPictureWorld.java
in the
ps03_programs
folder you downloaded. You can
compile the file and run the program if you are interested. This file
has lots of examples of Picture manipulations. You are not required
to do anything with this file for the assignment. We have included it
only because it demonstrates lots of Picture examples. Most of the
examples are commented out so that the menu of the applet is not
cluttered, but feel free to un-comment whatever examples you are
interested in experimenting with.
(This file is essentially the same as the SimplePictureWorld.java
file we studied in the first PictureWorld lecture.)
For the first two problem sets, you met two of the instructors in their office hours. This week, you must meet the third one of us! Go to the third instructor's office hours and secure a sticker (you cannot receive a sticker from an instructor whom you have previously received a sticker from). If you cannot make office hours, you must schedule an appointment. Place the sticker on the problem set cover page. Now you have met all three of us!
Escher's Knitting Patterns
Dutch artist M. C. Escher is renowned for creating artwork based on interlocking patterns and visual playfulness. Here we will experiment with "knitting patterns" that Escher himself experimented with in 1943. (For more details on Escher's artwork, see M.C. Escher: Visions of Symmetry by Doris Schattschneider, W.H. Freeman and Company, 1990).
Escher's knitting patterns were based on the following two primitive patterns that he designed:
|
|
We will call these patterns A and B. We can make many variants of A an B by rotating them, flipping them, and painting their stripes different colors. These variants of A and B can be combined to form an amazing number of patterns that resemble the weave patterns of knitted yarn. For example, study the following four knitting patterns, all of whose basic squares are versions of A and B that have been rotated, flipped, and colored in various ways.
|
|
|
|
Playing with Knitting Patterns in PictureWorld
PictureWorld
is a perfect tool for experimenting with Escher's
knitting patterns. The file KnitWorld.java
in the ps03_programs
folder contains
several methods that aid in this experimentation. Colored versions of
the A and B patterns are created by the following two black-box
methods in KnitWorld
.
public Picture A(Color c1, Color c2, Color c3, Color c4, Color c5) public Picture B(Color c1, Color c2, Color c3, Color c4, Color c5)
The five color arguments of A and B paint the patterns in the way indicated by the following examples:
|
|
The tileKnit
method is useful for constructing many simple knitting patterns:
public Picture tileKnit (Picture p1, Picture p2, Picture p3, Picture p4) { return fourSame(fourSame(fourPics(p1, p2, p3, p4))); }
The fourSame
and fourPics
methods are
similar to those presented in lecture and lab:
public Picture fourSame (Picture p) { return fourPics(p, p, p, p); } public Picture fourPics (Picture p1, Picture p2, Picture p3, Picture p4) { return above(beside(p1,p2), beside(p3,p4)); }
Using the above methods, plus the usual picture combinators of
PictureWorld, it is possible to make pictures for all four knitting
patterns shown above. Here is a knit1()
method, parameterized over two colors, that generates the
knit1
pattern shown above:
public Picture knit1(Color c1, Color c2) { Picture A1 = A(c1, c2, c1, c1, c2); Picture B1 = B(c2, c1, c2 ,c2, c1); return tileKnit(A1, B1, A1, B1); }
The knit2()
method is similiar in structure to
knit1()
, but uses different colorings, flips, and
rotations:
public Picture knit2(Color c1, Color c2) { Picture A1 = A(c1, c2, c1, c2, c1); Picture B1 = B(c2, c1, c2 ,c1, c2); return tileKnit(flipVertically(B1), flipVertically(A1), clockwise180(B1), clockwise180(A1)); }
The knit3()
method is parameterized
over three colors rather than two:
public Picture knit3(Color c1, Color c2, Color c3) { return tileKnit(B(c1, c2, c1, c3, c1), clockwise90(B(c1, c3, c2, c2, c1)), flipHorizontally(B(c1, c3, c1, c2, c1)), flipHorizontally(clockwise90(A(c1, c2, c3, c3, c1)))); }
The knit4
pattern has a more complex
repetition pattern than can be described by tileKnit()
.
Two alternative knit4()
methods are shown below. Both
methods produce identical pictures. The first uses 12 local
variables to refer to the various intermediary pictures that
are generated while constructing the final picture pattern. The
second uses only 2 local variables to refer to intermediary pictures,
instead preferring to nest expressions by having fruitful method
invocations, which return Picture objects, serve as arguments to other
methods with Picture parameters. The two alternative methods for capturing the
knit4
pattern represent two different problem solving approaches
that achieve the same result.
public Picture knit4(Color c1, Color c2) { Picture A1 = A(c1, c2, c1, c1, c2); Picture B1 = B(c1, c2, c1, c2, c1); Picture A2 = A(c2, c1, c2, c1, c2); Picture B2 = B(c2, c1, c2, c2, c1); Picture A1_clockwise270 = clockwise270(A1); Picture B1_flipHorizontally = flipHorizontally(B1); Picture B2_flipDiagonally = flipDiagonally(B2); Picture B2_clockwise270 = clockwise270(B2); Picture A2_flipHorizontally = flipHorizontally(A2); Picture A1_flipDiagonally = flipDiagonally(A1); Picture tile1 = fourPics(B1, A1_clockwise270, B1_flipHorizontally, B2_flipDiagonally); Picture tile2 = fourPics(A2, B2_clockwise270, A2_flipHorizontally, A1_flipDiagonally); return fourSame(fourPics(tile1, tile2, tile1, tile2)); }
public Picture knit4_alternative(Color c1, Color c2) { Picture tile1 = fourPics(B(c1, c2, c1, c2, c1), clockwise270(A(c1, c2, c1, c1, c2)), flipHorizontally(B(c1, c2, c1, c2, c1)), flipDiagonally(B(c2, c1, c2, c2, c1))); Picture tile2 = fourPics(A(c2, c1, c2, c1, c2), clockwise270(B(c2, c1, c2, c2, c1)), flipHorizontally(A(c2, c1, c2, c1, c2)), flipDiagonally(A(c1, c2, c1, c1, c2))); return fourSame(fourPics(tile1, tile2, tile1, tile2)); }
Your Task
In this problem, you will define methods that draw the following
two knitting patterns: knit5
(shown in the LEFT column)
and knit6
(shown in the RIGHT
column). knit5()
is parameterized over four colors, while
knit6()
is parameterized over two colors. The particular
knit5
patterns shown below are created by the invocation
that you can read in the top of the KnitWorld picture (in the yellow
bar at the top of the image). For example, the top left
knit5
pattern in created by this invocation:
knit5(Color.red, Color.magenta, Color.blue,
Color.green)
.
|
|
|
|
|
|
The file KnitWorld.java
contains the skeletons of two
methods that you should flesh out :
public Picture knit5(Color c1, Color c2, Color c3, Color c4) { // Put your definition here. } public Picture knit6(Color c1, Color c2) { // Put your definition here. }
To begin this problem, first study the knit1()
through knit4()
methods above and
convince yourself that they do in fact draw the four knitting
patterns shown in the previous section. Your solutions to
knit5()
and knit6()
will be similar to the knit1()
through
knit4()
. Next, you should carefully study
the knit5
and knit6
patterns to determine which rotations, flips, and colorings of the
basic patterns A and B are employed. The final step is to encode your
findings in Java code in the method bodies of knit5()
and knit6()
. You may find it helpful to
define your own auxiliary methods in addition to defining
knit5()
and knit6()
.
To make testing a little easier, we have included a folder
Test
which contains working examples of the patterns you
need to make so that you can compare your work with the examples (but,
alas, no Java code!). There are two different ways to see the examples. (1) You can
start Dr. Java and open the file CS111.txt in the Test
folder that you
downloaded with ps03_programs
, click on the "Interactions" tab at the
bottom of the Dr. Java window and type "java KnitWorldSoln" in the "Interactions"
pane. (2) Alternatively, using
a web browser (e.g., Mozilla Firefox, Apple Safari, Internet Explorer),
open the file KnitWorldSoln.html
in the Test
folder that
you downloaded with ps03_programs
. You can choose
knit5
and knit6
from the menu to compare these examples
with your own work.
Blithe Buggle, co-founder of the Buggle Bagel Ruggle Company, has
been looking for new ways to expand her company's product line.
Although the bagel rugs marketed by the company are popular, they are
difficult to manufacture because of the labor costs (each rug is
hand-drawn by a Buggle) and and raw material costs (bagels cost more
than you think!). Blithe thinks the company should diversify to
produce other products with interesting designs, such as
quilts,wallpaper, and sweaters. Blithe is currently experimenting
with the picture drawing software presented in CS111 to design
quilts. Here is an example of one of Blithe's quilt designs, which we
will call quilt1
.
quilt1()
You and several other CS111 students have been hired as interns at
the Buggle Bagel Ruggle Company to help Blithe design quilts. Your
project is to use PictureWorld
to generate the quilt design shown
above. The quilt above is just one sample of the quilt design. Your
code will contain methods that take color parameters, and therefore
your code will be able to generate lots of different quilts, in the
same pattern as above, but with color variation. This description of
the assignment will use the quilt above as an example, but keep in
mind that your code must be generic and able to handle different
color variations of the above pattern. There is a file called
QuiltWorld.java
in the ps03_programs
folder.
All the methods that you will define for this problem will be in the
QuiltWorld
class. Your goal is to flesh out the skeleton
of the quilt1()
method so that it returns a picture
corresponding to the quilt shown above. This picture is ultimately
generated by combining primitive pictures generated by the following
two black-box methods:
public
Picture patch (Color c)
Returns a rectangular patch of colorc
with a black border that fills a given picture frame.
public
Picture triangles(Color c1, Color c2)
Returns a picture that consists of two triangles filling the given picture frame: a black-bordered triangle of colorc1
in the lower left corner of the frame; and a black-bordered triangle of colorc2
in the upper right corner of the frame.
For example, below are the pictures generated by some sample
invocations of these methods:
|
|
Divide, Conquer, and Glue
The key to solving the problem of defining quilt1()
is to note that
the picture can be decomposed into smaller pictures that are used
more than once in the larger picture. For example, the upper right
quadrant is a picture that we'll call corner
:
corner(Color.red, Color.blue, Color.green, Color.darkGray, Color.cyan, Color.magenta)
The whole picture can be decomposed into four copies of
corner
that have different rotations. Once we figure out
how to define the corner
picture, we can combine four
rotated copies of the picture to form the desired quilt picture. This
is an excellent illustration of the divide, conquer, and glue
problem solving strategy we will use throughout this course:
corner()
.corner
.corner
to construct our
quilt
.But how do we solve the problem of defining the
corner
picture? By applying the divide, conquer, and
glue strategy again! In this case, corner
naturally
decomposes into four quadrants:
|
|
|
|
We give the names quadrant1
, quadrant2
, and
quadrant3
to each distinct pattern. We notice that
quadrant2
is used twice in the corner
! We can
continue to use divide, conquer, and glue to decompose each quadrant
above into smaller and smaller pictures. When does the process stop?
When we get to pictures so small that they are trivial to solve. In
this case the trivial pictures are those generated by the
patch()
and triangles()
methods.
A general principle of computer science is “never write any piece of code more than once.” If you find yourself writing the same or similar code more than once in your program, you should write methods that capture the patterns of the repeated code and invoke the methods instead.
The divide, conquer, and glue process of defining quilt1()
naturally exposes the need for numerous auxiliary methods. As part of
working on this assignment, you should define and use the following
methods. Skeletons for all of these methods can be found in
QuiltWorld.java
.
public
Picture patch_2x2 (Color c)
Returns a picture consisting of four rectangular patches of colorc
with black lines between the patches. (Remember thatpatch(c)
returns a picture with a black border.)
public
Picture triangles_2x2 (Color c1, Color c2)
Returns a picture similar totriangles(c1, c2)
except that each large triangle is composed out of three smaller fragments (two triangles and a rectangle).
public
Picture LL (Picture p)
Returns a picture which divides the picture space into four quadrants and places the given picture in the lower left corner.
public
Picture LLNest (Picture p1, Picture p2)
Returns a picture which places picturep2
over the lower left corner of picturep1
.
Here are example invocations of the four methods above:
|
|
|
|
All of the methods in the PictureWorld
and QuiltWorld
contracts
are available to you. At a minimum, you should have methods that
correspond to each pattern described above. The
QuiltWorld.java
file has skeletons for all the methods
that you must define. In addition to that, you should define
additional methods which capture patterns that are used over and over
again. It is also helpful to define local variables within
your methods to give names to pictures that you generate as part of
your solution.
The quadrant3
pattern is made up of invocations of
LLNest()
and triangles()
. You do not need
anything else.
To make testing a little easier, we have included a folder
Test
that contains working examples of the patterns you
need to make so that you can compare your work with the examples (but,
alas, no Java code!). There are two different ways to see the examples. (1) You can
start Dr. Java and open the file CS111.txt in the Test
folder that you
downloaded with ps03_programs
, click on the "Interactions" tab at the
bottom of the Dr. Java window and type "java QuiltWorldSoln" in the "Interactions"
pane. (2) Alternatively, using
a web browser (e.g., Mozilla Firefox, Apple Safari, Internet Explorer),
open the file QuiltWorldSoln.html
in the Test
folder that
you downloaded with ps03_programs
.
You can choose components of your design, such as LL
or LLNest
to compare them to your work.
Oh no! Blithe has just designed this new quilt shown below, using
the same pattern as above, but with different colors. She forgot how
she actually created this one. She hires you to figure out which
Color parameters were used in what order to create the pattern below.
To solve this problem, write a new method called quilt2()
that produces the quilt shown below.
quilt2()