## Description

The purpose of this lab is to ensure that you are confident with – and have had

a lot of practice at – writing small clear functions that give precise control over

repetitive tasks. The lab is divided into three almost independent sections. Be

careful that you don’t ruin the work you did for one section while you are

working on the next.

Section A – Conversions

A1. Remembering how to start

Remind yourself of how to write the most basic repetitive function of all, one that

takes two parameters, A and B, and just prints all the numbers from A to B inclusive.

This will be the starting point for everything this week, so type it in, and make

absolutely sure that you have got it right, and it really works.

A2. Exotic Canada

You could adapt that function to count differently. Make a new version of it that

counts in steps of five, so that if you said “numbers(10, 90);” in main, your

program would print 10 15 20 25 30 … 85 90. Test it, make sure you got it

right.

Now imagine that you are taking a trip to some wild and exotic part of the world

where they use the metric system. Canada perhaps. You’ll be driving, and don’t want

to get a ticket for going too slow, so you want a conversion table to translate miles per

hour into kilometres per hour. One mile is 1.609344 km.

Adapt your function so that it doesn’t just print numbers, but prints mph to kph

conversions instead. Where it used to print X, it should now print X mph is Y kph.

The first few lines of output would look something like this

10 mph is 16 kph.

15 mph is 24 kph.

20 mph is 32 kph.

25 mph is 40 kph.

But there’s a complication. You will also be visiting the Mayor of Toronto, and he

likes to measure speed in miles per minute (not grams as you may have thought). So

what you need is a three way conversion like this.

10 mph is 16 kph or 0.17 mpm.

15 mph is 24 kph or 0.25 mpm.

20 mph is 32 kph or 0.33 mpm.

25 mph is 40 kph or 0.42 mpm.

You are probably seeing some ugly output now, with lots of distracting extra

digits. When a program calculates (for example) 10*1.609344, it gets a very

accurate result, 16.093444). Usually, precision is what you want, but in this case it

doesn’t help. To throw away all the digits after the decimal point, and reduce the

value to an int, the C++ expression is

(int)(10*1.609344)

Yes, you do need all those brackets, and of course it works for all numbers with

decimal points in them, not just 10*1.609344. It is even better if you round the

result to the nearest int. The trick for that is

(int)(10*1.609344 + 0.5)

which works for all positive values.

But that makes sense only for kilometres per hour. Kilometres are close enough to

miles that we don’t want to see any digits after the decimal point. Miles per minute

are another thing altogether. We want exactly two digits after the point. You can

probably work out how to reach that goal.

Section B – ASCII Art

B1. Stars

Go back to your basic counting function from A1, and this time adapt and adopt it in

a different way. Make a function that has one parameter N, which just prints a row of

N stars. That’s it, nothing complicated, stars(7) should just print “*******”.

Your function in A1 had two parameters, but this time we want a function that has

only one parameter.

B2. Dots

Now make another function almost identical to that, but it should print dots instead of

stars. dots(7) should just print “…….”. How are you going to test it? If you

just print spaces, you don’t see anything.

B3. Dots and Spaces

Now make another function that takes two parameters A and B, and prints A dots

followed by B stars followed by A dots followed by a new line. dotssstars(3,

4) should just print “…****…”. Remember that having functions that use

other functions to do most of their work is a good design technique.

B4. Another adaptation

Thinking about how you controlled repetition so far, write yet another function that

takes two parameters A and B. This one should count down from A to 1, and at the

same time count up from B in steps of 2. That sounds pointlessly complicated, but

one little example will make it clear: sequence(5, 1) should print

5 1

4 3

3 5

2 7

1 9

B5. Combining

Still remembering the idea of little functions using other little functions to do their

jobs, write another function just like sequence, except that it doesn’t print the

numbers, it uses them as parameters to dotssstars. This new function will draw

triangles: as an example triangle(5, 1) should print

….*….

…***…

..*****..

.*******.

*********

Not very spectacular I admit, but it’s all good practice.

Section C – Circles

C1. A circle

One way to draw an approximate circle is to draw a straight line a short distance, then

turn a small amount to the right. Repeat that so many times that all the turns add up to

360 degrees, and you’ll be back at the starting point. If the steps are small enough,

nobody will be able to tell the difference between that and an exact circle. Computer

monitors aren’t really very sharp, so the steps don’t need to be really really small, just

small.

Do it. Write a function that draws a circle. You should be able to control the size of

the circle by altering its parameters.

This is how you get the most accurate value for pi in C++:

const double pi = acos(-1.0);

C2. Weaponising

Now your circle is going to be the wheel of a cannon.

Given the position of the bottom of the wheel and the

aiming angle (x, y, a), you should be able to make a simple

cannon anywhere, aiming at any angle you want, such as 30

degrees (from vertical, shown to the left) or 75 degrees

(below).

If you need some help with to get the shape right, there are some formulas on the next pages.

That’s the END of the lab. The rest is just if you need a bit of help with the shape:

This is the cannon sitting on a wheel. The wheel’s radius is r.

a is the aiming angle.

L1 is the distance from the back of the cannon to the wheel’s axle, L2 is the rest of the

length.

Like all cannons it is wider at the back (w1) than the front (w2).

G is the point on the ground where the wheel rests. Its coordinates are (xg, yg).

C is the exact position of the axle, its coordinates are (xc, yc).

P is the easiest point to start drawing the body of the cannon from, coordinates (xp, yp).

E is the point where the ball pops out when it is fired, coordinates (xe, ye).

This is a simplified picture of the body of the cannon shown with its “bounding box”.

The point is to illustrate the difference between the real length of the cannon (len) and

the sum L1+L2.

The angle shown as b is also helpful when drawing the shape. When the cannon is

aimed at angle a, the heading for the bottom line is (a-b). Don’t forget that all angles are

computed in radians.

xc = xg

yc = yg – r

b = asin((w1-w2)/2/(L1+L2))

xp = xc – L1 * sin(a-b)

yp = yc + L1 * cos(a-b)

len = (L1+L2) * cos(b)

Finally, to find the point E, we need two extra values:

d is the distance between points P and E

g is the angle from point P to point E if the cannon lies flat as in the third diagram.

d = sqrt(len*len + w1*w1/4)

g = asin(w1/2/d)

xe = xp + d * sin(a-g)

ye = yp – d * cos(a-g)