*Generative Art*, Chapter 3, with study of the discussion of trigonometry and its use in drawing curves. However, you really should draw on the notes from class on Monday, 03/24.

Write a method, `connect`, which takes as arguments an integer,
*n* and a floating point value, *p*. The method should plot
*n* points, evenly spaced around a circle. Then, for each pair of
points, it should draw a gray line between them with probability
*p*

connect(16,0.05) connect(16,0.125) connect(16,0.45) connect(16,1.0)

* Tip #1:* This problem involves the drawing of

* Tip #2:* The key insight for the line drawing is to observe
that from each point, we're going to consider every other point (what kind of
control structure does this kind of nested iteration?). Then we *might*
draw a line to it (with probability p). As a first attempt, try just drawing
the lines. Then go back and study the discussion we had in class on probability techniques. In particular, the

Make a second version of your `connect()` method, which connects lines on a *spiral* instead (again, see below for the basics). Exactly where you connect lines in this case is up to you. Perhaps have one end of each line at the enter of the spiral? Connect lines between points on opposite sides of a spiral (i.e. the angle + PI/2)? It's up to you.

Implement methods for drawing spirographs,by providing methods for drawing
hypotrochoids and epicycloids. *Before proceeding, take some time to read
the tutorial material on this, below*. Read it carefully! There isn't much
coding to do in this part, and once you can follow the tutorial material, you'll
that a lot of it is just translation of formulae into code. Without the
background material, however, this part will be extremely difficult or even
impossible.

You are to write two methods, `hypotrochoid` and `epitrochoid`.
Both methods should take at least three floating-point
arguments—*R*, *r*, and *p*— corresponding
(respectively) to the radius of the ring, of the disc, and of the pen with
respect to the disc's center. The methods should draw the corresponding
hypotrochoids or epitrochoid.

The basic version of this would simply keep a variable *t*, denoting
the angle of revolution, which is incremented by some small increment, say,
0.01. We can then define a "limit", for the largest *t* value, and
iteratively draw points on the curve until this limit is reached: this limit,
of course, is the closest integer to the period of the curve.

int period = ... ; float t = 0.0; float incr = 0.01; int numPlots = (int) (period / incr);

Computing the period of a curve is straightforward, but it requires concepts that we have not learned in this class: recursion and roundoff error in
floating point numbers. I suggest instead that you add a 4th parameter to your
methods, `b`, which will be the number of complete revolutions of the
disc around the ring (see the discussion of "period", above). This means you'll
have to compute the correct argument to *b* by hand in order to draw a
complete curve, but that's okay for this project. Indeed, if you just pick some
value out of the air—say, 100 revolutions—and the period is less
than that, you'll just be drawing on top of the curve you've already drawn.
That makes for a very slightly slower method, but you won't be able to tell the
difference.

Exercise your creativity here! Add a parameter to control the color of the curve, or choose a random color each time. Perhaps, too, an option to draw multiple curves, in order to make combined images. Control of pen width? Switching pen color part-way through a drawing? What else?

In addition to the three mandatory parameters and "revolutions" parameter, my
version includes a "fast" option parameter (which causes `incr` to be set
at 0.1 rather than 0.01), and a "clear drawing" option which allows the drawing
of multiple curves. On execution, each method chooses a random pen color

Here are some sample calls, and the resulting images (note that the last two combine in my version). The "fast drawing" option is set to `false` in every case:

epitrochoid(0.32,0.1,0.2,5,false,true); hypotrochoid(0.64,0.2,0.4,5,false,true); epitrochoid(0.54,0.26,0.26,13,false,true); hypotrochoid(0.84,0.24,0.4,2,false,false);

Below is the code we developed in class for the `circelplot()` method, which takes two arguments, integers *n* and *r* and plots a set of *n* evenly-spaced dots around a circle with radius *r*:

circleplot(width/2,height/2,100,8); circleplot(width/2,height/2,100,16); circleplot(width/2,height/2,100,128);

Here's the circle plotting code that we developed in class on Wednesday (03/30):

void circleplot(int cx, int cy, int r, int n) { // Plot a circle around a point (cx,cy), with radius r, using n dots float ang = 0.0; float dAng = (2*PI) / n; strokeWeight(1); fill(0, 0, 255); noStroke(); int i = 0; while (i < n) { float x = cx + cos(ang)*r; float y = cy + sin(ang)*r; ellipse(x, y, 10, 10); ang += dAng; i++; } }

There are other forms of curve you can draw. One we did in class changes the computation of the *(x,y)* coordinates to multiply each by the current value of the angle (which is increasing). This plots what is known as the *Archimedean spiral*. Here's a version that does this *r* revolutions of the spril, drawing *n* points on each complete revolution, with a *scaling factor* on the spiral of *s* (which, in Pearson's presentation is the "increasing radius" value):

void spiralplot(int cx, int cy int n, int s, int r) { float ang = 0.0; float dAng = (2*PI) / n; stroke(0, 0, 255); strokeWeight(3); while (ang < r*(2*PI)) { float x = cx + ang * cos(ang)*s; float y = cy + ang * sin(ang)*s; ellipse(x, y,5,5); ang += dAng; } }

(The scaling factor is necessary to avoid drawing a spiral that is packed together too tightly to see the lines of its curve.)

Try this one out with, for example

spiralplot(width/2,height/2,numc,2,9);

The Spirograph is a classic toy that allows one to make beautiful designs based on curves known as epitrochoids and hypotrochoids. If you've never seen one (and most of you probably haven't, as they have only recently come back into production after decades of unavailability), you can read about them at http://en.wikipedia.org/wiki/Spirograph and at http://mathworld.wolfram.com/Spirograph.html.

To understand these curves, imagine a a larger ring of radius *R*,
fixed against a surface. Now imagine a disc of radius *r* to which we
attach a pen, at a distance *p* from the center of the disc.

Figure 1. The hypotrochoid *R = 5*, *r = 3*, *p = 5*, which has a period of *2π3*, or 3 rotations of the disc

*(Source: Wikimedia Commons)*

Let's start by considering the hyptrochoid (the more common of the Spirograph componenents, since it's a lot easier to keep a physical disc stable inside a ring than outside). To draw these, we will calculate the *(x,y)* coordinates of a point on the curve by computing each coordinate in terms of *t*, the angle that we have rotated the disc around the ring. Under this view, the *(x,y)* coordinates of the pen at angle
*t* are given by

So to draw the curve, we just need to pick a few values of *t* and
plot a point at the *(x,y)* coordinates of each one!

Which values of *t*? We want to make sure of two things. First, we
want to pick values that are evenly spaced across some range. This will give
the illusion of an unbroken curve, even though we're not plotting every visible
pixel in our drawing. Basically, we figure out how big a *t* range to
draw, break that into a set of *n* evenly spaced values, and plot each
point. My solutions take the size of the *t* range, divide that by
either 0.1 or 0.01 (depending on whether I want a faster drawing or a more
precise one), take the closest integer value to that, and use the result as an increment that I repeatedly add to the
current *t* value.

Now for the "*t* range". Study the animation in Figure 1. You'll
notice that it takes 3 rotations of the disc around the ring to complete the
curve. In other words, the total angle of rotation is 2π3: this is called
the *period* of the curve. In general, the period of a hypotrochoid can
be calculated from the radii of the disc and the ring. Take the fraction
*r/(R-r)* in reduced form: *r/(R-r) = b/a*. The period is
*2πb*, so we need *b* rotations to complete the curve.

Figure 2. The epitrochoid *R = 3*, *r = 1*, *p = 0.5*, which has a period of *2π*, or 1 rotation of the disc

*(Source: Wikimedia Commons)*

An epitrochoid curve is very similar to a hypotrochoid, except that we roll the disc around the outside of the ring. To draw these curves, we again look at both the *x* and *y* coordinates as functions of the angle of rotation. In an epitrochoid, these coordinates are given by

The techniques for drawing epitrochoids are very similar to those for hypotrochoids.

As discussed above, the ratio of *r* and *R-r* controls the
period of the curve: it is *2πb*, where *b/a = r/(R-r)* in
reduced form.

The difference between *r* and *p* controls the detail in the
curves, in the form of apparent direction changes. If *r = p*, then both
epitrochoids and hypotrochoids will have a number of *cusps* (sharp
corners in the curve): these curves are known as *epicycloids* and
*hypocycloids*. If *r < p*, then the curve will have a number of
"loops" in its drawing (going outwards for hypotrochoids, in for epitrochoids).
Finally, if * r > p*, then the curve will have no loops at all, but
rather a series of "bends" (outwards or inwards), as in the epitrochoid of
Figure 2.

The ratio of *R* and *r* controls how many of these "changes"
occur in the curve (cusps, bends, or loops). If *R/r = p/q* in reduced
form, the curve has *p* cusps, bends, or loops. This leads to some
surprisingly complicated designs with very subtle changes. For example, a curve
with *R=0.9 & r = 0.3* will have 3 changes over a period of 2π,
while a curve with *R=0.9 & r = 0.301* will have 900 over a period of
2π301.

Your code must be syntactically correct. Any solution that contains a syntax error anywhere will receive no credit for that problem. If you run into any trouble here, please ask me for help.

Naturally, your code must be behaviorally correct, though partial credit will be given for partial solutions.

As with all assignments for this course, submit the folder containing your Processing sketches. This should be a single folder named "`hw5`", which will contain your two sketches. You do not need to submit a paper printout of anything. Again, the turnin directory is

`~lasseter/classes/cpsc120/username`

John H. E. Lasseter