translate code blocks to Ludus, learn some things, take some notes
This commit is contained in:
parent
32cf547efb
commit
9890a6f0c2
265
ch_1_intro.md
265
ch_1_intro.md
|
@ -120,7 +120,6 @@ Get a lot of it.
|
|||
Be careful using this glue, though; it is very flammable.
|
||||
Don't smoke and glue at the same time.
|
||||
|
||||
|
||||
### Dialects
|
||||
Unfortunately, there is not just one Logo.
|
||||
While some Logos are more alike than others, most have quirks.
|
||||
|
@ -196,7 +195,7 @@ Review the turtle reference commands: `FD`, `BK`, `PU`, `PD`, `RT` `LT`.
|
|||
In the cartesian system, the destination is the important thing; in the turtle reference system, it's the trip.
|
||||
|
||||
### Making shapes
|
||||
Let's draw a simpel shape using turtle reference commands.
|
||||
Let's draw a simple shape using turtle reference commands.
|
||||
Suppose you would like the turtle to draw a square box located at the center of the screen (usually the origin of the coordinate system).
|
||||
Here are the steps you would take:
|
||||
|
||||
|
@ -216,10 +215,10 @@ That's it.
|
|||
The turtle has walked around the four sides of a size 50 box, arriving back to where it started.
|
||||
These prose commands would translate into Logo as:
|
||||
|
||||
1. `FD 50 RT 90`
|
||||
2. `FD 50 RT 90`
|
||||
3. `FD 50 RT 90`
|
||||
4. `FD 50 RT 90`
|
||||
1. `forward! (50); right! (0.25)`
|
||||
2. `forward! (50); right! (0.25)`
|
||||
3. `forward! (50); right! (0.25)`
|
||||
4. `forward! (50); right! (0.25)`
|
||||
|
||||
The third and last step would be to type these commands on the keyboard.
|
||||
And here is what you will see.
|
||||
|
@ -234,11 +233,13 @@ Review the `REPEAT` command; it is exactly what we need here.
|
|||
Try it.
|
||||
|
||||
```
|
||||
CG
|
||||
REPEAT 4 [FD 50 RT 90]
|
||||
repeat 4 {
|
||||
forward! (50)
|
||||
right! (0.25)
|
||||
}
|
||||
```
|
||||
|
||||
Notice that the line `REPEAT 4 [FD 50 RT 90]` is a kind of operational definition of what a square is: a square is four sides, four `FD` commands, with each side joined at right angles to the next, the `RT 90` commands.
|
||||
Notice that the line `repeat 4 { forward! (50); right! (0.25) }` is a kind of operational definition of what a square is: a square is four sides, four `FD` commands, with each side joined at right angles to the next, the `RT 90` commands.
|
||||
That's tidy, but it's still a bore to type two lines each time you want a size 50 box on the screen.
|
||||
After all, you may want to draw 100 boxes.
|
||||
|
||||
|
@ -257,9 +258,12 @@ Let's get on with writing the necessary procedure.
|
|||
Here it is:
|
||||
|
||||
```
|
||||
TO BOX50
|
||||
REPEAT 4 [FD 50 RT 90]
|
||||
END
|
||||
fn box50! () -> {
|
||||
repeat 4 {
|
||||
forward! (50)
|
||||
right! (0.25)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Logo will add `BOX50` to all its other commands.
|
||||
|
@ -276,7 +280,14 @@ Keep track of what you are doing in your notebook so that you can reconstruct yo
|
|||
Here is a simple command that wraps boxes around the screen:
|
||||
|
||||
```
|
||||
REPEAT 25 [PD BOX50 PU RT 15 FD 60 LT 15]
|
||||
repeat 25 {
|
||||
pendown! ()
|
||||
box50! ()
|
||||
penup! ()
|
||||
right! (inv (24))
|
||||
forward! (60)
|
||||
left! (inv (24))
|
||||
}
|
||||
```
|
||||
|
||||
### Wrapped boxes
|
||||
|
@ -314,9 +325,12 @@ You can now draw boxes of any size from, say, 1 unit to 5000 units.
|
|||
Use this example as a "pattern" for incorporating an argument into a procedure.
|
||||
|
||||
```
|
||||
TO BOX :EDGE
|
||||
REPEAT 4 [FD :EDGE RT 90]
|
||||
END
|
||||
fn box! (edge) -> {
|
||||
repeat 4 {
|
||||
forward! (edge)
|
||||
right! (0.25)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Putting a demonsuation procedure together
|
||||
|
@ -339,13 +353,22 @@ If you wish to show off with several designs, you could design specific Logo pro
|
|||
Here is an example of such a demonstration procedure:
|
||||
|
||||
```
|
||||
TO DEMO
|
||||
; A demonstration procedure to show off a design
|
||||
; produced from multiple boxes of different sizes.
|
||||
REPEAT 4 [BOX 100 BOX 98 BOX 96 BOX 75 BOX 40
|
||||
BOX 35 BOX 30 RT 90]
|
||||
END
|
||||
& A demonstration procedure to show off a design
|
||||
& produced from multiple boxes of different sizes.
|
||||
fn demo () -> {
|
||||
repeat 4 {
|
||||
box! (100)
|
||||
box! (98)
|
||||
box! (96)
|
||||
box! (75)
|
||||
box! (40)
|
||||
box! (35)
|
||||
box! (30)
|
||||
right! (0.25)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To see the pattern defined by `DEMO`, type it:
|
||||
|
||||
{{Figure 4: Differently sized boxes. Top of p. 15.}}
|
||||
|
@ -399,9 +422,12 @@ Why not call the generalized procedure `NGON` for n-sided polygon?
|
|||
Look again at the procedure BOX and decide what needs to be changed to turn `BOX` into `NGON`.
|
||||
|
||||
```
|
||||
TO BOX :EDGE
|
||||
REPEAT4 [FD :EDGE RT 90]
|
||||
END
|
||||
fn box! (edge) -> {
|
||||
repeat 4 {
|
||||
forward! (edge)
|
||||
right! (0.25)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You need to add a second argument `:N`.
|
||||
|
@ -423,13 +449,16 @@ Review the Logo notation to add, subtract, multiply, and divide.)
|
|||
You are ready to write the new procedure NGON:
|
||||
|
||||
```
|
||||
TO NGON :N :EDGE
|
||||
REPEAT :N [FD :EDGE RT 360/:N]
|
||||
END
|
||||
fn ngon! (n, edge) -> {
|
||||
repeat n {
|
||||
forward! (edge)
|
||||
right! (inv (n))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Try it out.
|
||||
Notice that when: N becomes large, the drawn figure becomes a circle (almost).
|
||||
Notice that when `:N` becomes large, the drawn figure becomes a circle (almost).
|
||||
Carry out some clever visual experiments with `NGON`s.
|
||||
|
||||
### Some observations
|
||||
|
@ -481,12 +510,12 @@ For a 90% shrinkage I would use `:GROWTH`=.9."
|
|||
|
||||
### A procedure to spin polygons
|
||||
```
|
||||
TO SPINGON :N :EDGE :ANGLE :GROWTH
|
||||
NGON :N :EDGE
|
||||
RT :ANGLE
|
||||
SPINGON :N (:EDGE*:GROWTH) :ANGLE :GROWTH
|
||||
; Here is the recursion.
|
||||
END
|
||||
fn spingon! (n, edge, angle, growth) -> {
|
||||
ngon! (n, edge)
|
||||
right! (angle)
|
||||
spingon! (n, mult (edge, growth), angle, growth)
|
||||
& Here is the recursion
|
||||
}
|
||||
```
|
||||
|
||||
What is new here?
|
||||
|
@ -501,14 +530,17 @@ Will `SPINGON` ever stop? Try it out.
|
|||
|
||||
### Some spingons
|
||||
```
|
||||
SPINGON 30 2 10 1.02 95
|
||||
spingon! (30, 2, inv (36), 1.02, 95)
|
||||
```
|
||||
|
||||
{{Figure 7: Snail-ish spingon. Top of p. 21.}}
|
||||
|
||||
```
|
||||
HOME CG REPEAT 3 [SPINGON 4 120 0 .95 50 RT 90]
|
||||
SPINGON 4 120 0 .95 19
|
||||
repeat! 3 {
|
||||
spingon! (4, 120, 0, 0.95, 50)
|
||||
right! (0.25)
|
||||
}
|
||||
spingon! (40, 120, 0, 0.25, 19)
|
||||
```
|
||||
|
||||
{{Figure 8: Frame-ish spingons. Bottom of p. 21.}}
|
||||
|
@ -524,15 +556,17 @@ Review the conditional commands in Logo.
|
|||
Using the `IF` phrase, everything becomes very tidy.
|
||||
|
||||
```
|
||||
TO SPINGON :N :EDGE :ANGLE :GROWTH :TIMES
|
||||
; Note the new argument above.
|
||||
IF :TIMES < 1 [STOP]
|
||||
; This is the conditional stopper.
|
||||
NGON :N :EDGE
|
||||
RT :ANGLE
|
||||
SPINGON :N (:EDGE*:GROWTH) :ANGLE :GROWTH (:TIMES-1)
|
||||
; Note the new argument above.
|
||||
END
|
||||
fn spingon! (n, edge, angle, growth, times) -> {
|
||||
& Note the new argument above.
|
||||
if lt? (times, 1) then :stop
|
||||
& This is the conditional stopper.
|
||||
else {
|
||||
ngon! (n, edge)
|
||||
rt! (angle)
|
||||
spingon! (n, mult (edge, growth), angle, growth, dec (times))
|
||||
& Note the new argument above.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Boring logistics
|
||||
|
@ -560,15 +594,17 @@ Here is an example from this chapter.
|
|||
Notice the use of comments, too.
|
||||
|
||||
```
|
||||
TO SPINGON :N :EDGE :ANGLE :GROWTH :TIMES
|
||||
; Note the new argument above.
|
||||
IF :TIMES < 1 [STOP]
|
||||
; This is the conditional stopper.
|
||||
NGON :N :EDGE
|
||||
RT: ANGLE
|
||||
SPINGON :N (:EDGE*:GROWTH) :ANGLE :GROWTH (:TIMES-1)
|
||||
; Note the new argument above.
|
||||
END
|
||||
fn spingon! (n, edge, angle, growth, times) -> {
|
||||
& Note the new argument above.
|
||||
if lt? (times, 1) then :stop
|
||||
& This is the conditional stopper.
|
||||
else {
|
||||
ngon! (n, edge)
|
||||
rt! (angle)
|
||||
spingon! (n, mult (edge, growht), angle, growht, dec (times))
|
||||
& Note the new argument above.
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Third, the _body structuring_ rule.
|
||||
|
@ -579,13 +615,15 @@ Here is an example.
|
|||
Notice that the Logo material within the [repeat brackets] would have been difficult to read if the long statement had not been divided into several short lines.
|
||||
|
||||
```
|
||||
TO SQUIGGLE :A :B :N
|
||||
REPEAT :N [ FD :A -
|
||||
RT 130 -
|
||||
FD :A -
|
||||
RT 50 -
|
||||
BK :B ]
|
||||
END
|
||||
fn squiggle! (a, b, n) -> {
|
||||
repeat n {
|
||||
forward! (a)
|
||||
rightt! (inv (3))
|
||||
forward! (a)
|
||||
right! (inv (6))
|
||||
back! (b)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The symbol "`-`" indicates, of course, that the return key should not be used becausethe Logo statement continues.
|
||||
|
@ -614,7 +652,7 @@ This is another way to ask yourself what information must be given to `CNGON` so
|
|||
That means that the first line of the new procedure will look like this:
|
||||
|
||||
```
|
||||
CNGON :N :RAD
|
||||
cngon! (n, rad)
|
||||
```
|
||||
|
||||
Second, imagine yourself as the turtle.
|
||||
|
@ -689,14 +727,19 @@ No more words are necessary.
|
|||
Here it is.
|
||||
|
||||
```
|
||||
TO CNGON :N :RAD
|
||||
PU FD :RAD
|
||||
RT (angle) PD
|
||||
NGON :N (edge)
|
||||
LT (angle)
|
||||
PU BK :RAD PD
|
||||
END
|
||||
fn cngon! (n, rad) -> {
|
||||
penup! ()
|
||||
forward! (rad)
|
||||
right! (::angle::)
|
||||
pendown! ()
|
||||
ngon! (n, ::edge::)
|
||||
left! (::angle::)
|
||||
penup! ()
|
||||
back! (rad)
|
||||
pendown! ()
|
||||
}
|
||||
```
|
||||
|
||||
The procedure is sketched.
|
||||
And we know what we know and what we don't.
|
||||
The two amounts, (angle) and (edge), are still unknown.
|
||||
|
@ -719,31 +762,31 @@ The external angle is the turning angle used in `NGON`.
|
|||
What about the internal angles, labeled b.
|
||||
We need some work here:
|
||||
|
||||
(1) c = 360/n,
|
||||
(1) c = 1/n,
|
||||
|
||||
(2) c + b = 180.
|
||||
(2) c + b = 1/2.
|
||||
|
||||
Putting these two equations together and solving for b gives
|
||||
|
||||
(3) b=180*(n-2)/n.
|
||||
(3) b = 1/2 - 1/n.
|
||||
|
||||
We are now ready to handle the first problem: Find d in terms of n.
|
||||
|
||||
(4) d + b/2 = 180.
|
||||
(4) d + b/2 = 1/2.
|
||||
|
||||
Putting (3) and (4) together and solving for d gives
|
||||
|
||||
(5) d = 180 - 90*(n-2)/n <---**First problem solved**.
|
||||
(5) d = 1/4 + 1/2n <---**First problem solved**.
|
||||
|
||||
OK, now look at the second problem: Find e in terms of R and n.
|
||||
|
||||
(6) sin (a/2) = (e/2)/R,
|
||||
|
||||
(7) a = 360/n.
|
||||
(7) a = 1/n.
|
||||
|
||||
Putting (7) and (6) togetherand solving for e gives
|
||||
|
||||
(8) e = 2\*R\*sin(180/n) <---**Second problem solved**.
|
||||
(8) e = 2\*R\*sin(1/2n) <---**Second problem solved**.
|
||||
|
||||
Review the following trig functions: sine, cosine, and tangent.
|
||||
What is ani arctangent?
|
||||
|
@ -754,34 +797,45 @@ Glue them on the inside cover of your notebook.
|
|||
Here's how far we have gotten with `CNGON`:
|
||||
|
||||
```
|
||||
TO CNGON :N :RAD
|
||||
PU FD:RAD
|
||||
RT (angle) PD
|
||||
NGON :N (edge)
|
||||
LT (angle)
|
||||
PU BK :RAD PD
|
||||
END
|
||||
fn cngon! (n, rad) -> {
|
||||
penup! ()
|
||||
forward! (rad)
|
||||
right! (::angle::)
|
||||
pendown! ()
|
||||
ngon! (n, ::edge::)
|
||||
left! (::angle::)
|
||||
penup! ()
|
||||
back! (rad)
|
||||
pendown! ()
|
||||
}
|
||||
```
|
||||
|
||||
Now we can replace `(angle)` and `(edge)` with the needed expressions.
|
||||
Here is the finished `CNGON`:
|
||||
|
||||
```
|
||||
TO CNGON :N :RAD
|
||||
PU FD :RAD
|
||||
RT 180 - (90*(:N-2)/:N) PD
|
||||
NGON :N (2*:RAD*SIN (180/:N))
|
||||
LT 180 - (90*(:N-2)/:N)
|
||||
PU BK :RAD PD
|
||||
END
|
||||
fn cngon! (n, rad) -> {
|
||||
let angle = sub (inv (2), inv (n))
|
||||
let edge = mult (2, rad, sin (inv (mult (2, n))))
|
||||
|
||||
penup! ()
|
||||
forward! (rad)
|
||||
right! (angle)
|
||||
pendown! ()
|
||||
ngon! (n, edge)
|
||||
left! (angle)
|
||||
penup! ()
|
||||
back! (rad)
|
||||
pendown! ()
|
||||
}
|
||||
```
|
||||
|
||||
### Lessons and tips
|
||||
When solving visual problems, like this CNGON thing, try to break the single big problem down into several smaller problems.
|
||||
When solving visual problems, like this `CNGON` thing, try to break the single big problem down into several smaller problems.
|
||||
Solve each of the small problems in turn, and then plug the little solutions together to form one big solution.
|
||||
|
||||
#### Exercise 1.2
|
||||
Put together one or more DEMO procedures that make imaginative use of the ideas presented and reviewed in this chapter.
|
||||
Put together one or more `DEMO` procedures that make imaginative use of the ideas presented and reviewed in this chapter.
|
||||
Modify every procedure in the chapter.
|
||||
Make them act more strangely.
|
||||
|
||||
|
@ -825,3 +879,26 @@ Don't forget the following tricks:
|
|||
research.
|
||||
6. Translate the words into Logo commands.
|
||||
7. Test it out with realistic and totally outlandish argument values
|
||||
|
||||
### Notes for adaptation
|
||||
* Don't use abbreviations everywhere!
|
||||
* Stopping recursion looks different.
|
||||
- This will be different once we get actors and Ludus runs in a different thread. Is this a prerequisite?
|
||||
* Math is harder, since we don't have familiar arithmetic operators.
|
||||
* A few places there are arbitrary degrees; figure out how to make this friendlier.
|
||||
- Throughout, replace degrees with turns.
|
||||
* Consider a helper function, `double`, to simplify the math for `cngon!`.
|
||||
* Procedure -> function, throughout.
|
||||
* The canvas doesn't (currently) wrap, so the example of many squares with wrapping needs to be a bit different.
|
||||
* Prepping the annotated SVGs will be a thing.
|
||||
- Do we want hand-drawn stuff? Consider using the iPad.
|
||||
* This we do not need here:
|
||||
- Appeals to a manual
|
||||
- The `-` character to continue a line
|
||||
* Things we do need that are absent (in no particular order):
|
||||
- `let` bindings
|
||||
- M-expression math
|
||||
- A discussion of turns instead of degrees
|
||||
- A discussion of empty parens/function calls
|
||||
- A discussion of bangs in names
|
||||
- A discussion of question marks in names
|
||||
|
|
Loading…
Reference in New Issue
Block a user