Wednesday, July 15, 2020

Stewart Chapter 9: Chaos in the Cosmos

Table of Contents

1. Introduction
2. A Rapoport Geometry Problem
3. Another Geometry Problem
4. Shapelore Learning 14-4: The Wheelex and Wheelwhy Evennesses
5. Music: "Twelve Days of Christmath," "Angle Dance," "GCF/LCM"
6. Reblogging: Number Bases
7. Calculating the Cosmos Chapter 9: Chaos in the Cosmos
8. Lemay Chapter 10: Simple Animation and Threads
9. More About Animation in Java
10. Conclusion

Introduction

Well, the first two dominoes have fallen. The two largest California school districts -- LA and San Diego -- have announced that distance learning will continue through the start of the year. I'm subbing for neither LAUSD nor SDUSD. But, as we saw four months ago, whatever these two districts do, the rest of the districts in Southern California will follow.

I actually haven't blogged much about the reopening plans for our schools yet. Last night, one of my districts (the older of the two) held a special board meeting. They came up with one of the more interesting plans I've seen so far -- a four-stage reopening plan. Stage 1 is full online learning, while Stage 4 is full in-person learning. Stage 2 is something that appears to be unique to this district. I've decided to devote my next post to a full description of all four stages, as well as the role of substitute teachers like me in each stage.

Again, I can't help but wonder what the students from my old charter school are doing now. While I am sympathetic to the Class of 2020 for losing its graduation, my eighth graders from the old school will be graduating high school in 2021. I assume that since they attended my old charter, most of them will be attending charter high schools and hence aren't directly affected by the LAUSD school closure decision. Nevertheless, I figure that at least some charters will follow suit and remain shut as long as the district is. Therefore my old eighth graders ended their junior year with distance learning, and will at least begin their senior year with the same.

I'll continue this discussion in my next post. For now, it's time to proceed with our summer projects.

A Rapoport Geometry Problem

I'm starting today's post with a Rapoport problem, and you know what that means -- she's finally written a Geometry problem on the calendar.

Today on her Daily Epsilon of Math 2020, Rebecca Rapoport writes:

Find x.

Once again, all of the given information is in an unlabeled diagram, so let me label it. In Rectangle ABCD, E is chosen between C and D such that AD = DE. Angle EAB = 3x.

We notice that Triangle ADE is an isosceles right triangle, so Angle DAE = 45. Then since Angles DAE and EAB are complementary, we write:

3x + 45 = 90
3x = 45
x = 15

Therefore the desired value of x must be 15 -- and of course, today's date is the fifteenth.

Another Geometry Problem

That's right -- believe it or not, Rapoport actually has two Geometry problems this week after going so long without any such problems. Here is her other problem:

What is the area of a triangle whose sides are length 5, 5, and 6?

Since we are given three sides of a triangle and we want the area, we could use Heron's Formula. But there is a much easier way to find the area if the triangle is isosceles -- which it is in this case.

In Lesson 5-1 of the U of Chicago text, we learn that the bisector of the vertex angle is the same line as the perpendicular bisector of the base. Thus this line divides our isosceles triangle into two congruent right triangles, each with leg 3 and hypotenuse 5. So we can use the Pythagorean Theorem to find the common leg of the right triangles:

a^2 + 3^2 = 5^2
a^2 + 9 = 25
a^2 = 16
a = 4

I decided to call the remaining leg a instead of b, in order to remind me that it's the altitude, or height, of the original isosceles triangle. (Of course, we didn't really need to use Pythagoras at all, since it's the well-known 3-4-5 right triangle.)

So our original figure is a triangle with height 4 and base 6. So its area is:

A = (1/2)(4)(6) = 12

Then again, if we didn't recognize this trick, we could have used Heron from the start:

s = (5 + 5 + 6)/2 = 16/2 = 8
A = sqrt(8(8-5)(8-5)(8-6))
A = sqrt(144) = 12

In either case the desired area must be 12 -- and of course, this problem was from Sunday the twelfth.

Shapelore Learning 14-4: The Wheelex and Wheelwhy Evennesses

Last Saturday was July 11th -- 7-Eleven Day, one of my favorite days of the year. Normally I'd go out to as many 7-Eleven stores as possible to get the free Slurpee. But this year, the 7-Eleven Day celebrations have been cancelled due to the coronavirus. (At least I made up for it by celebrating National Fry Day on Monday -- I ate the "new" fries at KFC. I place "new" in scare-quotes because they're actually like the fries the chain used to serve back in the 1990's.)

Instead, that day I celebrated Lambda Approximation Day -- Michael Hartl of the Tau Day website refers to half of pi as "lambda." Since lambda = 1.57... and there is no January 57th, I prefer to think about Lambda Approximation Day. Indeed, lambda is approximately 11/7 (half of 22/7 which approximates pi), and so Lambda Approximation Day is eleven days before Pi Approximation Day.

Note: The following YouTube video refers to pi/2 as "eta," but I prefer to define eta as e^(1/e) -- an important number related to tetration.



And hey -- if you wish, we can think of today as another type of "Lambda Day." Since the presenter David Butler is Australian, we can write today's date his way, with the day first -- 15/7. This matches 1.57..., the first three digits in lambda (or Butler's eta). So I wish you a happy Lambda Day today!

(Indeed, this resolves the problem some Australians and Europeans have with Pi Day -- March 14th has nothing to do with pi unless we write it with the month first, 3/14. But Lambda Day doesn't work unless we write it the international way, 15/7. On the other hand, Americans might not like Pi Approximation Day since it must be written the international way, 22/7. Yet Americans can celebrate a Lambda Approximation Day on November 7th, 11/7.)

Lesson 14-4 of the U of Chicago text is called "The Sine and Cosine Ratios." Recall that in my last post, I already gave a name for the tangent ratio -- ringslope -- and that I needed more time to come up with names for the sine and cosine ratios.

Well, since then I decided not to call the sine and cosine ratios ringwhy and ringex. Instead, I noticed that the word wheel comes from Old English -- and it suggests the circular motion associated with the functions more readily than ring does. Therefore "sine" and "cosine" are wheelwhy and wheelex -- and yes, this means that I'm going back and using wheelslope for "tangent."

Notice that the why in wheelwhy stands for the letter y, since after all, the sine function corresponds to the y-coordinate of a point on the wheel. Technically speaking, the letter y, if we were to spell out its name fully, is actually called wye, so the name should be wheelwye. It's just that why is more recognizable as a syllable pronounced y -- and noticed that last week, Laura Lemay used whys as the name of a variable containing y-coordinates (rather than wyes). But if you prefer, you can use the name wheelwye for the sine function.

By the way, I was thinking about the calculator button again, and the fact that calculators already have buttons labeled "sin" and "cos." So we ask, are there words in Anglish that begin with these letters, so that we don't have to change the button names?

I look at the Anglish wordbook and see some interesting words starting with "sin." Actually, sine is listed there as a pronoun meaning "his," "her," "its," or "their." That doesn't really help us here in Shapelore, since "his function" or "her function" doesn't make sense.

The word singale means "continuous," and indeed, the sine function is continuous. In fact, the phrase singale rimecraft is listed as a possible name for "Calculus."

I also see an even better word here -- sinwelt, which means "round" or "circular." Since we're trying to define sine as a circular function here, perhaps sinwelt can work here.

Unfortunately, there aren't as many good words starting with "cos" here. The only real words in the Anglish wordbook are cost and its derivatives. 

We could call the sine and cosine functions sinweltwhy and sinweltex, but then we'd have to explain to students why the "sin" button means sinweltwhy and not sinweltex. We could keep the "co-" prefix (even though it's Latin), and call the functions sinwelty and cosinwelty. Then when a student asks why we call it cosinwelty, we explain that since we can't pronounce sinweltx (and they never see the word sinweltex in this world), we use "co-" to indicate that it goes "with" the y, so it's the x. Then the buttons "sin" and "cos" are used for these functions.

We might also replace "co-" with "l-" or "el-" for "lambda," since it's still Lambda Day and we saw in the video how sine and cosine are related via right angles. But then again, the name elsinwelty doesn't help us with the "cos" button -- and if we're going to use the prefix "el-" instead of "l-" for euphony, then we might as well use the suffix "-ex" instead of "-x" and forget about "el-."

And of course, none of those names help us with the "tan" button, and the answer I gave last week (tawning) was already ad hoc. Therefore in the end, it's better just to use wheelwhy, wheelex, and wheelslope and forget about trying to match the letters on the buttons "sin," "cos," and "tan." We then use wheeloverslope for "cotangent," wheeloverex for "secant," and wheeloverwhy for "cosecant,"

As an aside, I recall that five years ago when I was tutoring Korean immigrants, they had problems figuring out how to pronounce "sin." One student kept saying sin, until I told him that the word sin is for their religion class, not math. Another guy noticed that "sin" is often followed by "theta," and so he kept calling it "sintheta."

The word evennesses in the title above means "ratios," so this is pure Anglish. I prefer keeping the Latin word "divide" and using "dividing" for "ratio" in our Plain English.

(Oh, and before we begin our Shapelore lesson, I've decided that I will no longer use the phrase "grandfathering in" to refer to Latin/French words that we're keeping in our Plain English. Instead, these are words that we're keeping in our simple language.)

OK, so let's begin our translation:

The wheelslope is the dividing of the lengths of two legs in a right threeside. When a leg is compared to the longestside, the wheelwhy or wheelex dividing results.

Here are the official definitions:

In right threeside ABC with right angle C,
the wheelwhy of A, written wy A, is leg withering A/longestside;
the wheelex of A, written wx A, is leg neighboring A/longestside.

In the above threeside, wy A = a/c and wx A = b/c. For any angle shapesame to A, these wheelwhy and wheelex dividings are the same because the angles would be in shapesame right threesides.

Here is the first example of this lesson:

1. Right threeside has side lengths as indicated. [AB = 13, AC = 12, BC = 5.] Find each worth.
a. wy A
b. wx A
c. wy B
d. wx B

Answer:
a. wy A = leg withering A/longestside = 5/13 = 0.3846.
b. wx A = leg neighboring A/longestside = 12/13 = 0.9231.
c. wy B = leg withering B/longestside = 12/13 = 0.9231.
d. wy B = leg neighboring B/longestside = 5/13 = 0.3846.

At this point, our text explains how "cosine" is short for "complement's sine." We're not using "co-," so there's no need to translate this. And then the text also explains the calculator buttons -- but again, I don't wish to discuss why the button for wy is "sin" and the button for wx is "cos." (A teacher could joke around and say "The button for 'wy' is called 'sin,' for sinwelt, which means 'circular.'" For at least one student will already know that "sin" means "sine" and then will call out our BS answer. So it's better just to say, "Well, an old name for wheelwhy is 'sine.'"

Let's just skip ahead to the next example:

2. Find exact values of wy 30 and wx 30.
Answer: Sketch a threeside as shown at the left. This is a 30-60-90 threeside, so the legs are x and xsqrt(3) and the longestside is 2x.

wy 30 = x/(2x) = 1/2.
wx 30 = xsqrt(3)/(2x) = sqrt(3)/2.

By the way, I notice that the text labeled the side opposite the 30-degree angle as x, yet this side is used to find the wheelwhy value rather than the wheelex value. Then again, there's nothing stopping us from labeling this side as y, or even a to separate it from the names wheelwhy and wheelex.

The text explains that Euler is the one who came up with the symbols "sin," "cos," and "tan." We'll just jump ahead to our last example:

3. Suppose a particular type of ladder is safe if the angle it makes with the the ground is from 65 to 80 degrees.
a. How far up on a vertical wall can a 30-foot ladder of this type reach? (We might wish to replace the word "vertical" here. The Anglish wordbook suggests upright, but we've already used this for the word "perpendicular." Then again, a vertical wall is one that is perpendicular to the ground.)
b. How far, at minimum, should it be placed from the base of the wall? (If desired, we can easily change "minimum" to least.)

Answer: First draw a picture.

In the shape drawn, part a needs BC and part b needs AC.

a. The leg withering 80 is desired. The longestside is known. So the wheelwhy should be used.
wy 80 = leg withering 80-degree angle/longestside
A calculator shows sin 80 = 0.985.
Standing in: 0.985 = BC/30.
Find BC: BC = 30 * 0.985 = 29.6 feet.
The ladder will reach about 29.6 feet high on the wall.

b. AC is the leg neighboring the 80-degree angle. This suggests using the wheelex.
wx 80 = leg neighboring 80-degree angle/longestside
A calculator shows cos 80 = 0.174.
Standing in: 0.174 = AC/30.
AC = 30 * 0.174 = 5.2 feet.
5.2 feet is 5 feet, 2.4 inches. You should place the ladder at least 5'3" away from the wall. Otherwise the ladder is too close to upright (either "perpendicular" or "vertical") to be used safely.

Check: The Pythagorish Provedsaying can check both answers at once.
Does AC^2 = BC^2 + AB^2?
Does (5.2)^2 + (29.6)^2 = 30^2?
The left side is 903.2, the right side is 900. This is close enough, given the approximations used for wy 80 and wx 80 and the rounding done to get 5.2 and 29.6. (If we need to change "approximations," I suppose nearnesses works, or else keep the French word "roundings.")

Let's try some of the exercises here -- the ones without diagrams.

1. Define: a. wy A. b. wx A.
Answer:
a. wy A = leg withering A/longestside.
b. wx A = leg neighboring A/longestside.

4. Give exact values (or worths) of a. wy 60 b. wx 60 c. wm 60. (The last one means wheelslope.)
Answer: a. wy 60 = sqrt(3)/2 b. wx 60 = 1/2 c. wm 60 = sqrt(3).

5. Give exact values (or worths) of a. wy 45 b. wx 45 c. wm 45.
Answer: a. wy 45 = sqrt(2)/2 b. wx 45 = sqrt(2)/2 c. wm 45 = 1.

7. Estimate (or "round") to the nearest thousandth: a. wy 13.2 b. wx 13.2.
Answer: a. wy 13.2 = 0.228. b. wx 13.2 = 0.974.

10 a. Use a calculator to estimate wy 89 to the nearest ten-thousandth.
     b. Give a Shapelorish reason why the worth is so near 1.
Answer: a. wy 89 = 0.9998.
b. Think of the ladder. If the angle were 89, the ladder is almost upright. So the height on the wall is almost the length of the ladder.

And as a bonus, let me add two more problems based on the Rapoport problems from earlier:

Using today's problem, find a. wy DAE b. wx DAE. c. wm DAE. (Answer: This is the same 45-degree angle as in #5, so we get a. wy 45 = sqrt(2)/2. b. wx 45 = sqrt(2)/2. c. wm 45 = 1.)

Using Sunday's problem, find wy, wx, and wm of a base angle of the original triangle. (Answer: we get wy A = a/c = 3/5 = 0.6, wx A = b/c = 4/5 = 0.8, wm A = a/b = 3/4 = 0.75.)

Well, we've finally done it. We've completed the two main trig lessons that I wanted to do in Shapelore, and we finally have new names for all of the trig functions.

Music: "Twelve Days of Christmath," "Angle Dance," "GCF/LCM"

We now proceed with the songs that I sang at the old charter school during Weeks 17-18. These are the weeks before and after winter break.

Let's begin with the last song I sang before winter break -- "Twelve Days of Christmath." (Yes, so it's still Christmas in July here on the blog.) This song originally comes from "mathemusician" Vi Hart, but my students didn't enjoy this song. Vi's version, after all, mentions several concepts that are too advanced for my middle school students. So I've since written an easier version that sticks to middle school math:

Vi's first verse is "the multiplicative identity." Even though many middle school students don't know what a multiplicative identity, the concept itself is simple -- even second graders should know that one times anything is the number itself.

Of course, Vi changes the words on every verse. Let's keep it simple and make it more like the original song, where the songs repeat each verse.

THE 12 DAYS OF CHRISTMATH

1. On the first day of Christmas, my true love gave to me,
     The multiplicative identity. (same as Vi)

2. ...The only even prime,... (same as Vi)
3. ...The number of spatial dimensions... (same as Vi)
4. ...The number of sides of a square...
5. ...Give me a high-five! (not mathematical, but a nice mid-song pick-me-up)
6. ...The smallest perfect number...
7. ...The most common lucky number... (same as Vi)
8. ....The number of corners of a cube...
9. ...The number it all goes back to... (reference to Square One's Nine, Nine, Nine)
10. ...The base of Arabic numerals (same as Vi)
11. ...The number the amp goes up to... (same as Vi)
12. ...The number in a dozen...

(Hmm, I wonder whether the fifth verse, with its "high-five," will work in the coronavirus era. I might just make it "an air high-five" instead.)

I also wrote a Mocha version of this song, using the simpler PLAY command:

https://www.haplessgenius.com/mocha/

10 FOR V=1 TO 4
20 PLAY "O2;L8;CC;L4;C;L8;FF;L4;F"
30 PLAY "L8;EFGAB-G;L2;A"
40 IF V=1 THEN 80
50 FOR X=V TO 2 STEP -1
60 PLAY "O3;L4;C;O2;L8;GA;L4;B-"
70 NEXT X 
80 PLAY "O3;L4;C;L8;D"
90 PLAY "O2;B-AF;L4;G;L2.;F"
100 NEXT V
110 FOR V=5 TO 12
120 PLAY "O2;L8;CC;L4;C;L8;FF;L4;F"
130 PLAY "L8;EFGAB-G;L2;A"
140 IF V=5 THEN 180
150 FOR X=V TO 6 STEP -1
160 PLAY "O3;L4;C;O2;L8;GAB-G"
170 NEXT X
180 PLAY "O3;L2;C;L4;D;O2;B;O3;L1;C"
190 PLAY "L8;C;O2;B-AG;L4;F"
200 PLAY "B-DF;L8;GFED;L4;C;L8;AB-"
210 PLAY "O3;L4;C;L8;D"
220 PLAY "O2;B-AF;L4;G;L2.;F"
230 NEXT V

As usual, click on "Sound" before you RUN the program. If I were to convert it to EDL, it will probably be in 20EDL using Degrees 20 to 9. Then Degree 15 becomes the tonic F, thus keeping the song in F major (and taking advantage of the F major triad on Degrees 15-12-10).

In fact, let me post the EDL version now:

NEW
1 N=8
5 GOSUB 300
10 FOR V=1 TO 4
20 GOSUB 400
40 IF V=1 THEN 80
50 FOR X=V TO 2 STEP -1
60 GOSUB 600
70 NEXT X
80 GOSUB 800
100 NEXT V
110 FOR V=5 TO 12
120 GOSUB 300
140 IF V=5 THEN 180
150 FOR X=V TO 6 STEP -1
160 GOSUB 600
170 NEXT X
180 GOSUB 1000
230 NEXT V
240 END
300 C=261-N*20:D=261-N*18:E=261-N*16
310 F=261-N*15:G=261-N*13:A=261-N*12
320 B=261-N*11:HC=261-N*10:HD=261-N*9
330 EN=2:QN=4:HN=8:DH=12:WN=16
340 RETURN
400 SOUND C,EN
410 SOUND C,EN
420 SOUND C,QN
430 SOUND F,EN
440 SOUND F,EN
450 SOUND F,QN
460 SOUND E,EN
470 SOUND F,EN
480 SOUND G,EN
490 SOUND A,EN
500 SOUND B,EN
510 SOUND F,HN
520 RETURN
600 SOUND HC,QN
610 SOUND G,EN
620 SOUND A,EN
630 SOUND B,QN
640 RETURN
800 SOUND HC,QN
810 SOUND HD,EN
820 SOUND B,EN
830 SOUND A,EN
840 SOUND F,EN
850 SOUND G,QN
860 SOUND F,DN
870 RETURN
1000 SOUND HC,HN
1010 SOUND HD,QN
1020 SOUND B,QN
1030 SOUND HC,WN
1040 SOUND HC,EN
1050 SOUND B,EN
1060 SOUND A,EN
1070 SOUND G,EN
1080 SOUND F,QN
1090 SOUND B,QN
1100 SOUND D,QN
1110 SOUND F,QN
1120 SOUND G,EN
1130 SOUND F,EN
1140 SOUND E,EN
1150 SOUND D,EN
1160 SOUND C,QN
1170 SOUND A,EN
1180 SOUND B,EN
1190 SOUND HC,QN
1200 SOUND HD,EN
1210 SOUND B,EN
1220 SOUND A,EN
1230 SOUND F,EN
1240 SOUND G,QN
1250 SOUND F,DH
1260 RETURN

This is clearly much more complicated than the PLAY version, which is why I don't recommend it for this type of song (unless it's a new song native to EDL rather than based on a real 12TET song). I can't use DATA since Mocha doesn't let us RESTORE the data relevant to the right part of the song.

So instead, I have GOSUB 300 initialize all the variables to what I need. So C is the Sound code for the note C, D for the note D, and so on. For the lengths, EN is an eighth note, QN is a quarter note, and so on. (Actually, it would be shorter just to use 2 for the eighth note, 4 for the quarter note, and 8 for the half note. But coders often prefer avoiding magic numbers in this case, instead using names that help us recall what they stand for.)

The second song I sang was Square One TV's "Angle Dance":


I post the lyrics to the song here, courtesy Barry Carter:

http://wordpress.barrycarter.org/index.php/2011/06/07/square-one-tv-more-lyrics/#.WHW0BxsrKUk

Angle Dance

Lead vocals by Larry Cedar

Featured vocals by Reg E. Cathey

The following song includes graphic descriptions of obtuse and acute angles.
Viewers who might be offended by this subject matter should not view this program.
I know all the angles
Angle Dancing’s the latest fad
Make two lines meet, add a throbbing beat
The results’ll drive you mad
If you learn all the angles
You can dance to my angle song
To start bend your knees forty-five degrees
Everybody crawl along
Angle Dance, Angle Dance
Find the point where two lines merge
Angle Dance, Angle Dance
Come, let’s make our paths converge
Once you know all the angles
A two-person square’s a breeze
It’s quite cut-and-dried; stretch one arm to the side
Raise the other one ninety degrees
Next hang a friend from the ceiling
If he loves you I know he won’t care
Grasp his hands real tight, get those angles right
There you’ve done it; you’ve made a square
Angle Dance, Angle Dance
Help me measure these angles please
Angle Dance, Angle Dance
We’re all doing it by degrees
Angle Dance, Angle Dance
Make a circular turn on your toe
Angle Dance, Angle Dance
In degrees spin three six zero
If you try you can make any angle
If you don’t there’s no excuse
This little beaut is called acute
And this wide one is obtuse
Now I’ve taught you the angles
You’re Angle Dancing hip
And if you’re inclined, you can go out and find
A spatial relationship
Angle Dance, Angle Dance
Come and join me, hun
Angle Dance, Angle Dance
Have some geometric fun
Angle Dance, Angle Dance
Let’s hope our math’s correct
Angle Dance, Angle Dance
Gee it’s great when lines connect
(Fade out, repeating last refrain)



The last song I sang was the GCF Song:

GCF!
Greatest Common Factor
GCF!
List every factor
GCF!
Circle the ones in common
GCF!
Choose the biggest one

LCM!
Least Common Multiple
LCM!
List some multiples
LCM!
Circle the ones in common
LCM!
Choose the smallest one

This song needs a new tune. I don't remember much about the tune, except for one thing -- the notes I sang during the first line "GCF!" are the actual musical notes G, C, and F.

Suppose I wanted to create an EDL tune for this song. I've been suggesting using the date to decide which EDL to choose -- since I sang this song on January 10th, 12th, and 13th that year, it suggests using either 10EDL or 12EDL. (I didn't sing on January 11th as it was an Early Out Wednesday.)

I believe that 12EDL best suits this song. That's because if the GCF Song is in the key of C, then the notes G and F correspond to the perfect fifth and fourth -- and 12EDL conveniently contains both the fifth and the fourth.

This isn't to say that 10EDL doesn't have its merits. Recall that, while I previously considered 12EDL to be the simplest EDL in which to compose music, 10EDL is playable as well. This scale is a sort of pseudo-pentatonic scale, with the interval 10/7 (a tritone) in place of a perfect fifth. Indeed, 10EDL contains the 5/4 major third, as opposed to the 6/5 minor third of 12EDL -- and I likely sang the original GCF Song in C major.

But the key to the GCF Song is in its name -- G, C, F. Therefore the perfect fourth is more important here than the major third. Since 12EDL has a perfect fourth while 10EDL doesn't (unless we count the 10/7 tritone as both a fourth and a fifth), 12EDL is the better scale, despite its minor third.

I've been avoiding posting new tunes during this summer project, since my main goal is to post the lyrics to my songs, not the tunes. But the GCF song is so simple that I'd like to let this be the first song this summer for which I'll write a tune.

Again, in my Halloween 2018 post I wrote a program in Mocha that generates Mocha music. The problem is that it's so tedious having to write that code over and over just to generate the tune -- and then erase the generating program in order to type in the code for the generated music.

Of course, if I still had the real computer that Mocha emulates, I could write a more robust program that I could save on a floppy disk. And indeed, that program could itself generate the code for the generated music. We've seen code that generates code before -- the quine programs. In this case, the generated code would be saved on the disk as a data file, but then I could run it as a program. (If I recall correctly, I actually did this back in the day when I had the real Mocha computer -- wrote code that saves more code in a file, then run that code as an executable program. But whatever I did back then had nothing to do with music.)

Instead, let me use a device on which I really can save programs -- my TI calculator. Here is the code that I wrote in 2018, converted to TI-BASIC:

PROGRAM:COMPOSE
:{0}->L1
:Disp "EDL"
:Input S
:Disp "?/4TIME"
:Input T
:Disp "MEASURE"
:Input Z
:For(A,1,Z)
:T->B
:While B
:randInt(1,B)->L
:4->C
:While C
:randInt(1,C)->M
:randInt(S/2,S)->L1(dim(L1)+1)
:LM->L1(dim(L1)+1)
:C-M->C
:End
:B-L->B
:End
:End
:L1

Here L1 is the list variable, obtained by pressing 2nd 1 on the calculator. The list consists of the numbers that we then place into the DATA lines on Mocha.

The new Mocha program begins as follows:

10 N=8 (or another appropriate number for the octave here)
20 FOR V=1 TO (enter correct number of verses here)
30 FOR X=1 TO (enter correct number of notes here)
40 READ A,T
50 SOUND 261-N*A,T
60 NEXT X
70 RESTORE
80 NEXT V
90 END

Then the DATA lines begin with Line 100.

Let's try our TI program and have it generate our GCF song. It first asks us to choose an EDL, and so we enter 12 for the 12EDL scale. Then it asks for a rhythm time signature. Hey -- since G, C, F are three notes, perhaps 3/4 time is best for this song, so we enter 3. Finally, we need to know how many measures in 3/4 time to generate. Well, each verse has eight lines, but four of them have already been decided as G, C, F, so we need to generate only the other four bars. So we enter 4.

Here is the list that it generates for our variable L1:

{0 7 3 6 1 12 3 10 1 8 3 9 1 10 9 9 3 11 6 10 2 7 4 12 1 6 1 11 1 8 1 12 4 12 2 11 2}

The first number in this list is zero. I used it because of the expression L1(dim(L1)+1) -- this means find the length ("dimension") of the list, add one, and then place the item in that new position (in other words, add the item to the end of the list). But it doesn't work unless there's at least one item already in the list -- which makes this slightly annoying. I avoid this problem by starting the list with the dummy element {0}. We just ignore the zero when building the DATA lines in Mocha.

The items corresponding to the first bar are 7, 3, 6, 1, 12, 3, 10, 1, 8, 3, 9, 1. These numbers alternate between pitch values and length values -- the lengths 3, 1, 3, 1, 3, 1 add up to 12 sixteenth notes, which is three quarter notes. In particular, the 3, 1 pattern indicates that we're following a dotted eighth note (3) with a sixteenth note (1). This produces six syllables, which is enough for the second line of our lyrics ("Greatest Common Factor").

The second bar produced by the TI is 10, 9, 9, 3. This is one reason why I often use 2/4 time instead of 3/4 with this algorithm -- the calculator tried to take the entire bar (three beats) and divide it into two notes, with the first note three times as long as the second. This works for quarter notes (dividing them into a dotted eighth and a sixteenth note), but not so well for dotted half notes.

When this happens, I just drop this bar and repeat the first bar. The lyrics that we're trying to fit here are "List every factor." We'll change the first note into a quarter note to fit the syllable "list." (Notice that I'm treating "every" as a two-syllable word, "ev'ry." If we kept it as three syllables, then the rhythm becomes "LIST e-VER-y FAC-tor," which sounds weird, more like "List a very factor.")

The third bar is 11, 6, 10, 2, 7, 4, but the line we want to match is "Circle the ones in common." So there aren't quite enough notes for all the syllables.

So instead, we'll skip to the fourth bar, which is 12, 1, 6, 1, 11, 1, 8, 1, 12, 4, 12, 2, 11, 2. There are seven notes for seven syllables, so this fits. Notice the rhythm here -- "circle the ones" are on the sixteenth notes, "IN" is on the quarter note, and "common" falls on eighth notes.

Since our fourth line nearly repeats the second line, the eighth line will nearly repeat the sixth. To me, it sounds the best to have "choose the biggest" on eighth notes and "one" on a quarter note.

There's one more thing that I'd like to change. The notes G-C-F, all on quarter notes, repeats four times, while the other lines repeat twice each. So instead, let's use the third bar generated by the TI for the fifth and seventh lines -- after all, it contains three notes for the three syllables. The notes won't be G-C-F, but at least it's a welcome change in the rhythm.

Now that we've figured out the rhythm, let's work on the tune. Here is our basic 12EDL scale:

Degree  Note
12          white A
11          lavender B
10          green C
9            white D
8            white E
7            red F#
6            white A

(Notice that this is in the key of A -- we'll worry about the key of C later.) We'll keep most of the notes as generated, with one change -- in the fourth bar (used for the sixth and eighth lines), the first three Degrees as 12, 6, 11, an abrupt octave jump played over sixteenth notes. I'll change this to 12, 12, 11 so that there isn't such a jump.

In this song, the minor third on Degree 10 falls only short notes (a sixteenth and an eighth). This leaves the door open just to sing a major third anyway, to match how I first sang in it class. But the Mocha version will play it as a minor third.

Now to convert the song to the key of C. Mocha has a white C at Degree 162 -- but unfortunately, 162 isn't a multiple of 12, since this is 12EDL. (Degree 162 works for 18EDL, but we didn't use it because 18EDL lacks a perfect fourth.) Degree 324 would be a white C, but it's out of Mocha range.

Degrees 156 and 168 are the closest available notes to C. Notice that Degree 168 is actually red B, a little below C. Degree 156, meanwhile, is thu C, which is closer to C#.

So this is the final version of our song:

NEW
10 N=13
20 FOR V=1 TO 2
30 FOR X=1 TO 35
40 READ A,T
50 SOUND 261-N*A,T
60 NEXT X
70 RESTORE
80 NEXT V
90 END
100 DATA 8,4,12,4,9,4
110 DATA 7,3,6,1,12,3,10,1,8,3,9,1
120 DATA 8,4,12,4,9,4
130 DATA 7,4,12,3,10,1,8,3,9,1
140 DATA 11,6,10,2,7,4
150 DATA 12,1,12,1,11,1,8,1,12,4,12,2,11,2
160 DATA 11,6,10,2,7,4
170 DATA 12,2,11,2,12,2,11,2,12,4

In the first line, N=13 gives us the key of thu C/C#. To make it red B, change it to N=14.

Based on the key of C, here are the lyrics of the song with the notes to sing. (I leave off G-C-F since you already know those notes.) I'll write the major third E even though the Mocha version will play the minor third Eb.

GCF!
Greatest Common Factor (A-highC-lowC-E-G-A)
GCF!
List every factor (A-lowC-E-G-A)
GCF! (D-E-A)
Circle the ones in common (lowC-C-D-G-low-C-C-D)
GCF! (D-E-A)
Choose the biggest one (lowC-D-lowC-D-lowC)

LCM! (G-lowC-F)
Least Common Multiple (A-highC-lowC-E-G-A)
LCM! (G-lowC-F)
List some multiples (A-lowC-E-G-A)
LCM! (D-E-A)
Circle the ones in common (lowC-C-D-G-low-C-C-D)
LCM! (D-E-A)
Choose the smallest one (lowC-D-lowC-D-lowC)

Notice that the LCM lines are the second verse of the same song, so that I must sing the notes G-C-F even during the LCM lines.

This is the process I must follow for the other songs -- come up with random notes, then move them around in order to fit the lyrics.

Reblogging: Number Bases

The last time I posted on July 15th was two years ago. But that post ended up being about nothing but traditionalists and problem solving, due to recent activity on the traditionalist blogs at the time.

This year, Barry Garelick has posted only once since my last post. His Lambda Approximation Day (that is, July 11th) post is about the verb "problem solve." But that post hasn't drawn very many comments yet.

With this lull in traditionalist activity -- combined with the fact that I really shouldn't be reblogging during the summer anyway -- it's a great time for a traditionalist-free post.

But in last year's post, I did write a little about number bases (as a traditionalist analogy). Let me cut out the traditionalist part and keep the number bases part in today's reblog:

I'm actually in a base 4 (quaternary) mood right now because of the recent Rapoport question. 

[2020 update: Yes, there were two number base problems on the Rapoport calendar this month. Each one involves both bases 4 and 5 -- one number is in base 4, the other in base 5, and we must combine them somehow and write the answer in base 10. I won't post those problems today since they involve two bases and I only want to reblog what I wrote about base 4 last year.]

{4} (default quaternary)

Imagine that we're teaching a math class, and that we've chosen quaternary as the starter base to introduce to our students. Here are some questions we might ask:

1. In decimal, the divisor (last-digit) rule applies to two, five, and ten. To what numbers does the divisor (last-digit) rule apply in quaternary?

This one should be easy -- in quaternary, the divisor rule applies only to two (2) and four (10).

2. Regular numbers have divisibility rules where we must check the last several digits (for four in decimal, we must check the last two digits for divisibility by four). To what numbers does the regular test apply in quaternary?

Even the regular test for four in decimal is a bit tricky. The next regular number, eight, requires checking the last three digits, but it might be doable if we piggyback on the rule for four. Sixteen, unfortunately, is too difficult to resolve in decimal.

On the other hand, regular tests in a base like quaternary are more important and much easier. To test for divisibility by eight (20), the last two digits must be -00 or -20. To test for divisibility by sixteen (100), the last two digits must be -00. For the next two powers of two (200 and 1000), we check the last three digits. If they're -000 or -200, the number is divisible by 200, and in the former case -000, the number is also divisible by 1000, and so on. Compare this to the difficult task for checking the fifth and sixth powers of two in decimal.

3. In decimal, the omega (sum-of-digits) rule applies to three and nine. Does the omega rule apply to three (3) in quaternary? Does it apply to nine (21)?

Students should be able to check that the omega rule applies to three but not nine. A counterexample for nine is nine itself -- nine is written as 21, and 2 + 1 = 3, which clearly isn't a multiple of nine.

10 (since we're still counting in quaternary). Why or why not?

As for "why," it's said that regular rules "extend upward," while omega rules "extend downward." So the regular rule in quaternary (and theoretically in decimal) works for any power of two. But the omega rule only works for the omega number (one less than the base) and any of its factors. In decimal, nine is the omega, and three inherits nine's omega properties. But in quaternary, three is the omega, so no other number inherits three's omega properties. The fact that nine is 3^2 doesn't mean anything in quaternary, just as 3^3 doesn't have a simple omega rule in decimal.

11. Describe an alpha rule for five (11) in quaternary.

There is an alpha rule for eleven in decimal.  But five is a more important prime than eleven. So in quaternary, we should resolve five (11) using just alpha, not cube alpha.

The alpha rule involves adding and subtracting alternate digits. For example:

21: 2 - 1 = 1, therefore 21 isn't a multiple of 11.
313: 3 - 1 + 3 = 11, therefore 313 is a multiple of 11.
3001: 3 - 0 + 0 - 1 = 2, therefore 3001 isn't a multiple of 11.

12. To what numbers does the cube alpha (1001) rule apply?

We factor 1001 is quaternary: 1001 = 11 * 31. Thus cube alpha applies to the primes five (11) as well as thirteen (31). In practice, cube alpha will be used for 31 only, since 11 is resolved by alpha itself (and it's not worth using cube alpha for an extra prime much larger than the alpha, if all we want to resolve is the alpha).

13. To what numbers does the cube omega rule apply?

In quaternary, cube omega is 333, one less than the cube of the base 1000. In decimal, cube omega only helps to resolve two large numbers, but cube omega is more useful in quaternary. We notice this by factoring 333 = 3 * 3 * 13. So not only does cube omega provide us an additional prime seven (13), but we can also do nine (3^2 = 21) -- which, as you recall, is unavailable with just omega. (In decimal, cube omega likewise gives us an extra power of three, 3^3, and a prime larger than 3^3.)

Bonus: Is there a divisibility rule for eleven (23) in quaternary?

The answer is no, if we allow divisibility tests up to cube alpha. The number eleven is resistant to intuitive divisibility tests -- we can show that unless eleven is resolved by divisor, omega, or alpha, it's resolved only by fifth-power omega/alpha. Fifth powers are too large to work with in any base except 2 (binary).

But as I mentioned in my last post, quaternary is easily convertible to binary -- one quaternary digit equals two binary digits. Then we apply fifth-power alpha to the binary number to resolve eleven.

I consider this to be a "bonus" question -- I wouldn't mention a rule for eleven with students unless it's an honors class. If we do give a rule for eleven, then we have divisibility rules for all two-digit numbers in quaternary. Of course, 100 is regular, 101 is square alpha, and 102 = 2 * 21, which we resolve as even + 21 (from cube omega). So the first prime we can't resolve is nineteen (103).

{a} (default decimal)


Calculating the Cosmos Chapter 9: Chaos in the Cosmos

Before we begin our Stewart reading, I'd like to point something out here. Chapter 8 was about comets, and as it turns out, a comet is currently visible -- Neowise. Its orbit is nearly parabolic, but it's actually elliptical with a very long period -- nearly 7,000 years.

But it's difficult to see Neowise from my house, though. The Southern California marine layer often makes it cloudy at night, even when it's mostly clear in the daytime. (Back on the Fourth of July, it was also hard to see the lunar eclipse that night, but I heard that the eclipse wasn't really spectacular at all.) Moreover, Neowise is currently near the northern horizon -- but here in Southern California there are mountains to the north, separating us from the Central Valley. Those mountains also obscure our view of the comet.

Oh well -- it might have been interesting to look up and see some of the objects from Stewart's book in the actual sky.

Chapter 9 of Ian Stewart's Calculating the Cosmos is called "Chaos in the Cosmos." As usual, it begins with a quote:

"This is highly irregular."

-- Airplane II: The Sequel

And the proper chapter begins:

"Pluto's moons are wobbly. Pluto has five satellites. Charon is spherical and unusually large compared to its primary, while Nix, Hydra, Kerberos, and Styx are tiny irregular lumps."

Today's chapter is all about chaos theory, and what it means for our solar system. I've mentioned chaos theory on the blog before, indeed in connection with Stewart's earlier books. Here the author mentions the dwarf planet and its moons as an example of a chaotic system:

"Pluto's wobbly moons are the breaking news on chaotic dynamics in the cosmos, but astronomers have discovered many examples of cosmic chaos, from fine details about tiny moons to the long-term future of the solar system."

So chaos is responsible for much of the apparent randomness in our universe:

"On the other hand, chaos is also responsible for patterns -- the spirals of galaxies may well be an example, as we'll also see in Chapter 12. Order creates chaos, and chaos creates order."

The most well-known example of chaos in our world is the so-called "butterfly effect" -- that a butterfly flapping its wings can cause a hurricane:

"The main potential source of misunderstanding is the word 'cause.' It's hard to see how the tiny amount of energy in the flap of a wing can create the huge energy in a hurricane."

Instead, what really happens is that weather is highly sensitive to initial conditions, with slight changes in initial conditions leading to huge differences later on:

"The current way round this annoying effect is to run many simulations with small random variations in initial conditions, and use the results to quantify how probable different predictions are."

Indeed, it's possible that if the initial gas cloud contained just one more, or one fewer, gas molecule before forming the solar system, our planet would not exist!

"So much for the clockwork universe. Before we get carried away by how incredibly unlikely this makes our existence, and invoking the divine hand of providence, we should take into account another aspect of the calculations."

And that's the idea that even if we change the initial conditions slightly, it's still likely that gas giants and about four rocky planets will form no matter what. This is "deterministic chaos":

"The first person to recognize the existence of deterministic chaos, and to gain some inkling of why it happens, was the great mathematician Henri Poincare."

I've actually written about Poincare before -- recall the Poincare Conjecture and the efforts to prove it, thereby earning the solver a million-dollar prize. But here Stewart refers to Poincare's earlier efforts to solve the three-body problem. A solution requires an infinite series that converges:

"Essentially, the sum of the series should get closer and closer to some specific number as you include more terms."

But unfortunately, Poincare's series did not converge:

"After the prize had been awarded and the official memoir had been printed but not yet distributed, Poincare had discovered a mistake -- he'd overlooked chaotic orbits."

It took another mathematician -- Stephen Smale -- to work these orbits out. (By the way, Stephen Smale is still alive. In fact, today, July 15th, is his 90th birthday. Happy Birthday, Stephen Smale!)

"The horseshoe geometry allows a rigorous proof that this system is chaotic, and that in some respects it behaves like a random sequence of coin tosses -- despite being completely deterministic. As the extent and richness of chaotic dynamics became apparent, the growing excitement triggered a lot of interest from the media, who dubbed the whole enterprise 'chaos theory.'"

Here the author includes a picture of Smale's horseshoe on the left. The square is repeatedly folded, creating a series of horizontal stripes. Reversing time and unfolding it converts these into similar vertical stripes. On the right, when the two sets of stripes cross, we get a homoclinic tangle. The dynamics -- obtained by repeatedly folding -- makes points jump around on the tangle, apparently at random. The complete tangle involves infinitely many lines.

One moon whose orbit was studied using chaos theory was Saturn's moon Hyperion:

"This predicted that Hyperion's orbit should interact chaotically with its spin, a prediction confirmed by solving the equations of motion numerically."

The next aspect to be considered was the axial tilt of the planets (the reason for the seasons):

"Planets, being almost spherical, spin at a regular rate about an axis that seems not to change, even over centuries."

But in reality, this spin axis does change. This change is most dramatic for the planet Mars:

"The two groups calculated what effect this has by analyzing the planet's dynamics. Wisdom's calculations show that the obliquity of Mars varies chaotically, ranging between 11 and 49 degrees."

Our planet's spin axis doesn't change as often, because of our large moon:

"Without it, Earth's obliquity would wander around between 0 and 85 degrees. On this alternative Earth, climactic conditions would be very different."

Indeed, it could be hot at the poles and cold at the equator at different times. We now move on to one of science's biggest mysteries -- what caused the dinosaurs to disappear?

"Towards the end of their reign dinosaurs coexisted with mammals, some quite large, and the disappearance of dinosaurs seems to have triggered a burst of mammalian evolution as the main competition was removed from the scene."

The usual theory was that the impact of an asteroid caused the extinction:

"But at least one asteroid from this group has the wrong chemistry, and in 2011 the timing of the break-up was estimated as 80 million years, which doesn't leave a long enough gap before the impact. One thing that has been established is how chaos causes asteroids to be flung out of their belt and end up hitting the Earth."

And indeed, the orbits of asteroids can be quite chaotic:

"What you'd observe wouldn't be an asteroid performing a drunkard's walk; it would be an asteroid whose orbital elements change chaotically from one orbit to the next."

And here Stewart includes a picture, of s numerically computed cross section of orbits near a periodic one, in accordance with the KAM theorem (named for the mathematicians who proved it). The author follows it with some graphs -- one the left is a spike in eccentricity (vertical axis). Horizontal axis is time. On the right are the other edges of the chaotic zone (solid lines) and orbital elements of asteroids (dots and crosses). Vertical axis is eccentricity, horizontal axis is major radius relative to that of Jupiter.

Stewart ends the chapter as follows:

"Jupiter takes a corner kick, Mars scores. And sometimes...just sometimes...Mars kicks it in our direction. And if the kick happens to be on target -- Mars one, dinosaurs nil."

Lemay Chapter 10: Simple Animation and Threads


Here's the link to today's lesson:

http://101.lv/learn/Java/ch10.htm


Lesson 10 of Laura Lemay's Teach Yourself Java in 21 Days! is called "Simple Animation and Threads," and here's how this chapter begins:

The first thing I ever saw Java do was an animation: a large red Hi there! that ran across the screen from the right to left. Even that simple form of animation was enough to make me stop and think, "this is really cool."

That sort of simple animation takes only a few methods to implement in Java, but those few methods are the basis for any Java applet that you want to update the screen dynamically-for something as simple as flashy animation applets, or for more complex applets that may need to be updated based on data they get from the user, from databases connected to over the network, or from any other source.

Animation in Java is accomplished through various interrelated parts of the Java Abstract Windowing Toolkit (awt). Today you'll learn the fundamentals of animation in Java: how the various parts of the system all work together so that you can create moving figures and dynamically updatable applets. 

This animation really sounds tricky! Perhaps I should have divided this chapter in two to make sure that I really understand each part, but I'm already falling behind where I want to be.

The author explains:

The paint() method, as you learned yesterday, is called whenever an applet needs to be painted-when the applet is initially drawn, when the window containing it is moved, or when another window is moved from over it. You can also, however, ask Java to repaint the applet at a time you choose. So, to change the appearance of what is on the screen, you construct the image or "frame" you want to paint, and then ask Java to paint this frame. If you do this repeatedly, and fast enough, you get animation inside your Java applet. That's all there is to it.

Where does all this take place? Not in the paint() method itself. All paint() does is put dots on the screen. paint(), in other words, is responsible only for the current frame of the animation. The real work of changing what paint() does, of modifying the frame for an animation, actually occurs somewhere else in the definition of your applet.

In that "somewhere else," you construct the frame (set variables for paint() to use, create Color or Font or other objects that paint() will need), and then call the repaint() method. repaint() is the trigger that causes Java to call paint() and causes your frame to get drawn.

OK, I sort of get this. But then Lemay also mentions something else, called "threads":

There's one more part to the animation mix that you'll have to know about, and that's threads. I'm going to discuss threads in a lot greater detail later on in this lesson (and in even more detail on Day 18, "Multithreading") but for now here's the basic idea: Anything you do in a Java program that runs continually and takes up a lot of processing time should run in its own thread. Animation is one of these things. To accomplish animation in Java, therefore, you use the start() method to start a thread, and then do all your animation processing inside the thread's run() method. This allows the animation to run on its own without interfering with any other parts of the program.

The best way to understand all of this is to look at the first listing:

Listing 10.1. The DigitalClock applet.
 1: import java.awt.Graphics;
 2: import java.awt.Font;
 3: import java.util.Date;
 4:
 5: public class DigitalClock extends java.applet.Applet 
 6:   implements Runnable {
 7: 
 8:   Font theFont = new Font("TimesRoman",Font.BOLD,24);
 9:  Date theDate;
10:   Thread runner;
11: 
12:   public void start() {
13:     if (runner == null) {
14:       runner = new Thread(this);
15:       runner.start();
16:     }
17:   }
18:
19:   public void stop() {
20:     if (runner != null) {
21:       runner.stop();
21:       runner = null;
22:     }
23:   }
24:  
25:   public void run() {
26:     while (true) {
27:       theDate = new Date();
28:       repaint();
29:      try { Thread.sleep(1000); }
30:       catch (InterruptedException e) { }
31:     }
32:   }
33: 
34:   public void paint(Graphics g) {
35:     g.setFont(theFont);
36:     g.drawString(theDate.toString(),10,50);
37:   }
38:}
On my compiler, Line 21 produces a warning -- the Thread.stop() method is "deprecated." In that case, I wonder what the "non-deprecated" method for stopping a thread is supposed to be.

I'm actually less confused by try and catch, because C++ has something similar. In particular, what we're catching is an "exception," which is sort of like an error. Lemay tells us that she'll explain exceptions next week (Day 17) -- and that's one week Lemay time, which is more like months our time. We're required to catch exceptions in the run() method, so the author must include it here, even though she's far away from explaining it.

But she definitely takes the time now to explain threads in more detail:

First, the analogy. A group of students is on a bus, on a field trip somewhere. To pass the time, the teachers are leading a sing-along. As the trip progresses, the students sing one song, then when that song is done, they sing another song. While different parts of the bus could sing different songs, it wouldn't sound very good, so the singing of one song monopolizes the time until its done, at which time another song can start.

I won't cut-and-paste everything written about threads here. Instead, we can see everything that needs to be done in the example above. That includes implements Runnable in Line 6, making a variable of type Thread in Line 10, having start() create the thread and stop() destroy it, and placing everything else needed for the animation in run().

The author warns us that the applets may "flicker." Since the second listing is identical to the first, we proceed to the third listing:


Listing 10.3. The ColorSwirl applet.
 1:  import java.awt.Graphics;
 2:  import java.awt.Color;
 3:  import java.awt.Font;
 4: 
 5: public class ColorSwirl extends java.applet.Applet
 6:     implements Runnable {
 7:
 8:    Font f = new Font("TimesRoman",Font.BOLD,48);
 9:    Color colors[] = new Color[50];
10:    Thread runThread;
11:
12:    public void start() {
13:        if (runThread == null) {
14:            runThread = new Thread(this);
15:            runThread.start();
16:        }
17:    }
18:
19:    public void stop() {
20:        if (runThread != null) {
21:            runThread.stop();
22:            runThread = null;
23:        }
24:    }
25:
26:    public void run() {
27:
28:        // initialize the color array
29:        float c = 0;
30:        for (int i = 0; i < colors.length; i++) {
31:            colors[i] =
32:            Color.getHSBColor(c, (float)1.0,(float)1.0);
33:            c += .02;
34:        }
35:
36:        // cycle through the colors
37:        int i = 0;
38:        while (true) {
39:            setForeground(colors[i]);
40:            repaint();
41:            i++;
42:            try { Thread.sleep(50); }
43:            catch (InterruptedException e) { }
44:            if (i == colors.length ) i = 0;
45:        }
46:    }
47:
48:    public void paint(Graphics g) {
49:        g.setFont(f);
50:        g.drawString("All the Swirly Colors", 15, 50);
51:    }
52: }
Lemay erroneously includes an extra bracket after the brace on the last line. Of course I leave it out.

OK, I definitely see the "flickering" now. We're told that to fix it, we must add the following just before the closing brace on the last line

public void update(Graphics g) {
   paint(g);
}

Hmm, I still see a little "flickering." I wonder whether I did something wrong here.

Let's try the fourth listing, which draws a checkerboard and moves a checker:

Listing 10.4. The Checkers applet.
 1:   import java.awt.Graphics;
 2:     import java.awt.Color;
 3: 
 4:   public class Checkers extends java.applet.Applet
 5:       implements Runnable {
 6: 
 7:       Thread runner;
 8:       int xpos;
 9: 
10:       public void start() {
11:          if (runner == null) {
12:              runner = new Thread(this);
13:              runner.start();
14:          }
15:      }
16: 
17:      public void stop() {
18:          if (runner != null) {
19:              runner.stop();
20:              runner = null;
21:          }
22:      }
23:  
24:  public void run() {
25:      setBackground(Color.blue);
26:      while (true) {
27:          for (xpos = 5; xpos <= 105; xpos+=4) {
28:              repaint();
29:              try { Thread.sleep(100); }
30:              catch (InterruptedException e) { }
31:          }
32:          xpos = 5;
33:      }
34:  }
35: 
36:      public void paint(Graphics g) {
37:          // Draw background
38:          g.setColor(Color.black);
39:         g.fillRect(0, 0, 100, 100);
40:          g.setColor(Color.white);
41:          g.fillRect(101, 0, 100, 100);
42: 
43:          // Draw checker
44:          g.setColor(Color.red);
45:          g.fillOval(xpos, 5, 90, 90);
46:     }
47:  }
And here we read about "clipping":

To limit what gets redrawn, you need a couple things. First, you need a way to restrict the drawing area so that each time paint() is called, only the part that needs to get redrawn actually gets redrawn. Fortunately, this is easy by using a mechanism called clipping. Clipping, part of the graphics class, enables you to restrict the drawing area to a small portion of the full screen; although the entire screen may get instructions to redraw, only the portions inside the clipping area are actually drawn.

Here is the final listing -- Checkers2 is the version that uses "clipping":


Listing 10.5. The final Checkers applet.
 1: import java.awt.Graphics;
 2: import java.awt.Color;
 3: 
 4: public class Checkers2 extends java.applet.Applet implements Runnable {
 5: 
 6:     Thread runner;
 7:     int xpos;
 8:     int ux1,ux2;
 9: 
10:     public void start() {
11:         if (runner == null) {
12:             runner = new Thread(this);
13:             runner.start();
14:         }
15:     }
16:
17:     public void stop() {
18:         if (runner != null) {
19:             runner.stop();
20:             runner = null;
21:         }
22:     }
23:
24:     public void run() {
25:        setBackground(Color.blue);
26:        while (true) {
27:          for (xpos = 5; xpos <= 105; xpos+=4) {
28:             if (xpos == 5) ux2 = size().width;
29:             else ux2 = xpos + 90;
30:             repaint();
31:             try { Thread.sleep(100); }
32:             catch (InterruptedException e) { }
33:             if (ux1 == 0) ux1 = xpos;
34:          }
35:          xpos = 5;
36:        }
37:    }
38: 
39:     public void update(Graphics g) {
40:         g.clipRect(ux1, 5, ux2 - ux1, 95);
41:         paint(g);
42:     }
43: 
44:     public void paint(Graphics g) {
45:         // Draw background
46:         g.setColor(Color.black);
47:         g.fillRect(0, 0, 100, 100);
48:         g.setColor(Color.white);
49:         g.fillRect(101, 0, 100, 100);
50: 
51:         // Draw checker
52:         g.setColor(Color.red);
53:         g.fillOval(xpos, 5, 90, 90);
54:
55:         // reset the drawing area
56:         ux1 = ux2 = 0;
57:     }
58:}
There is still a little flicker here, as the author warns us:

Q:
Even with the changes you made, the Checkers applet still flickers.
A:
And, unfortunately, it will continue to do so. Reducing the size of the drawing area by using clipping does reduce the flickering, but it doesn't stop it entirely. For many applets, using either of the methods described today may be enough to reduce animation flicker to the point where your applet looks good. To get totally flicker-free animation, you'll need to use a technique called double-buffering, which you'll learn about tomorrow.

(And as you know by now, "tomorrow" doesn't really mean tomorrow.) But that still doesn't explain why my ColorSwirl still flickers when Lemay claims it won't.

More About Animation in Java

Sometimes it's tough for me to come up with ideas for my own projects. Indeed, I wish that Lemay would assign some projects for me to try out.

Hey -- hold on a minute. She does make a suggestion, right at the beginning of the chapter:

The first thing I ever saw Java do was an animation: a large red Hi there! that ran across the screen from the right to left. Even that simple form of animation was enough to make me stop and think, "this is really cool."

So what are we waiting for? Let's try making this very animation. We see what the task is here -- the method run() must change the x-coordinate. More precisely, it must decrease it, since the text is to move from right to left.

Here's what I came up with:

import java.awt.Font;
import java.awt.Color;
import java.awt.Graphics;

public class HiThere extends java.applet.Applet
  implements Runnable {
   Font theFont = new Font("TimesRoman",Font.BOLD,24);
    Thread runner;
    int xpos;
  
    public void start() {
      if (runner == null) {
        runner = new Thread(this);
        runner.start();
      }
    }

    public void stop() {
      if (runner != null) {
        runner.stop();
        runner = null;
      }
    }
    
    public void run() {
      while (true) {
      for (xpos=105; xpos>=5; xpos-=4) {
      repaint();
           try { Thread.sleep(100); }
            catch (InterruptedException e) { }  
      }        
      }
    }
  
    public void paint(Graphics g) {
      g.setFont(theFont);
      g.setColor(Color.red);
      g.drawString("Hi there!",xpos,50);
    }

}

Of course, this animation still flickers. And Lemay's tricks for avoiding flicker won't work here, since we must clear the entire screen as the entire text is moving. I guess we'll just have to wait until "tomorrow" to learn more.

Conclusion

My next post is a biggie. Most districts are making their coronavirus plans for the new school year either this week or next week, so it's a great time for me to discuss these plans as well. My future as a sub, and the future of the blog, are at stake.

No comments:

Post a Comment