|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U
Length: 66912 (0x10560) Types: TextFile Notes: Uncompressed file
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z« └─⟦036c765ac⟧ └─⟦963b8d3a5⟧ »TeX3.0/MFdoc/answers.tex.Z« └─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89 └─⟦963b8d3a5⟧ »./tex82/MFdoc/answers.tex.Z« └─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦63303ae94⟧ »unix3.14/TeX3.14.tar.Z« └─⟦c58930e5c⟧ └─⟦963b8d3a5⟧ »TeX3.14/MFdoc/answers.tex.Z« └─⟦this⟧
\ansno2.1: Point $5=(100,0)$ is closer than any of the others. \ (See the diagram below.) \ansno2.2: \decreasehsize 15pc \rightfig A2a (13pc x 5pc) ^9pt False. But they all do have the same $y$~coordinate. \ansno2.3: 5 units to the {\sl left\/} of the reference point, and 15 units up. \ansno2.4: \restorehsize $(200,-60)$. \ansno2.5: $"top"\,"lft"\,z_1=(0,b)$; \ $"top"\,z_2=(a,b)$; \ $"top"\,"rt"\,z_3=(2a-1,b)$; \ $"bot"\,"lft"\,z_4=(0,0)$; \ $"bot"\,z_5=(a,0)$; \ $"bot"\,"rt"\,z_6=(2a-1,0)$. Adjacent characters will be separated by exactly one column of white pixels, if character is $2a$ pixels wide, because the right edge of black pixels is specified here to have the $x$~coordinate $2a-1$. \ansno2.6: $"right"=(1,0)$; $"left"=(-1,0)$; $"down"=(0,-1)$; $"up"=(0,1)$. \ansno2.7: True; this is $(2,3)-(5,-2)$. \ansno2.8: $0[z_1,z_2]=z_1$, because we move none of the way towards~$z_2$; similarly $1[z_1,z_2]$ simplifies to~$z_2$, because we move all of the way. If we keep going in the same direction until we've gone twice as far as the distance from $z_1$ to~$z_2$, we get to $2[z_1,z_2]$. But if we start at point~$z_1$ and face~$z_2$, then back up exactly half the distance between them, we wind up at $(-.5)[z_1,z_2]$. \ansno2.9: (a)~True; both are equal to $z_1+{1\over2}(z_2-z_1)$. (b)~False, but close; the right-hand side should be ${2\over3}z_1+{1\over3}z_2$. (c)~True; both are equal to $(1-t)z_1+tz_2$. \ansno2.10: There are several reasons. (1)~The equations in a \MF\ program should represent the programmer's intentions as directly as possible; it's hard to understand those intentions if you are shown only their ultimate consequences, since it's not easy to reconstruct algebraic manipulations that have gone on behind the scenes. (2)~It's easier and safer to let the computer do algebraic calculations, rather than to do them by hand. (3)~If the specifications for $z_1$ and $z_5$ change, the formula $\bigl({1\over2}[x_1,x_5],b\bigr)$ still gives a reasonable value for~$z_3$. It's almost always good to anticipate the need for subsequent modifications.\par However, the stated formula for $z_3$ isn't the only reasonable way to proceed. We could, for example, give two equations \begindisplay $x_3-x_1=x_5-x_3$;\qquad $y_3=b$; \enddisplay the first of these states that the horizontal distance from 1 to 3 is the same as the horizontal distance from 3 to~5. We'll see later that \MF\ is able to solve a wide variety of equations. \ansno2.11: The following four equations suffice to define the four unknown quantities $x_2$, $y_2$, $x_4$, and $y_4$: $z_4-z_2="whatever"\times"dir"\,20$; ${1\over2}[y_2,y_4]={2\over3}[y_3,y_1]$; $z_2="whatever"[z_1,z_3]$; $z_4="whatever"[z_3,z_5]$. ^^"whatever" ^^{dir} \ansno3.1: The direction at $z_2$ is parallel to the line $z_4\to z_3$, but the vector $z_4-z_3$ specifies a direction towards $z_4$, which is $180^\circ$ different from the direction $z_3-z_4$ that was discussed in the text. Thus, we have a difficult specification to meet, and \MF\ draws a pretzel-shaped curve that loops around in a way that's too ugly to show here. The first part of the path, from $z_4$ to $z_2$, is mirror symmetric about the line~$z1\to z5$ that bisects $z_4\to z_2$, so it starts out in a south-by-southwesterly direction; the second part is mirror symmetric about the vertical line that bisects $z_2\to z_3$, so when the curve ends at~$z_3$ it's traveling roughly northwest. The moral is: Don't specify a direction that runs opposite to (i.e., is the negative of) the one you really want. \ansno3.2: @draw@ $z_5\to z_4\{z_4-z_2\}\to z_1\to z_3\to z_6\{z_2-z_6\} \to\cycle$. \ansno4.1: (a)~An ellipse $0.8\pt$ tall and $0.2\pt$ wide (`$\,\vcenter{\hbox{\manual\nibc}}\,$'); \ (b)~A~circle of diameter $0.8\pt$ (rotation doesn't change a circle!); \ (c)~same as~(a). \ansno4.2: Six individual points will be drawn, instead of lines or curves. These points will be drawn with the current pen. However, for technical reasons explained in Chapter~24, the @draw@ command does its best work when it is moving the pen; the pixels you get at the endpoints of curves are not always what you would expect, especially at low resolutions. It is usually best to say `^@drawdot@' instead of `@draw@' when you are drawing only ^{one point}. \ansno4.3: True, for all of the pens discussed so far. But false in general, since we will see later that pens might extend further upward than downward; i.e., $t$~might be unequal to~$b$ in the equations for "top" and "bot". \ansno4.4: $x_2=x_1$; $x_3={1\over2}[x_2,x_4]$; $x_4=x_5$; $"bot"\,y_1=-o$; $"top"\,y_2=h+o$; $y_4=y_2$; $y_5=y_1$; @draw@ $z_1\to z_2$; @draw@ $z_2\to z_3$; @draw@ $z_3\to z_4$; @draw@ $z_4\to z_5$. We will learn later that the four @draw@ commands can be replaced by \begindisplay @draw@ $z_1\dashto z_2\dashto z_3\dashto z_4\dashto z_5$; \enddisplay in fact, this will make \MF\ run slightly faster. ^^{--} \ansno4.5: Either say `@fill@ $z_5\to z_4\to z_1\to z_3\to z_6\to z_5\to \cycle$', which doubles point~$z_5$ and abandons smoothness there, or `@fill@ $z_5\{\curl1\}\to z_4\to z_1\to z_3\to z_6\to \{\curl1\}\cycle$'. In the latter case you can omit either one of the ^{curl} specifications, but not both. \ansno4.6: After the six original points have been defined, say \begindisplay @fill@ $z_5\to z_4\to z_1\to z_3\to z_6\to\cycle$;\cr $z_0=(.8[x_1,x_2],.5[y_1,y_4])$;\cr @for@ $k=1$ @upto@ 6: $z_k'=.2[z_k,z_0]$; @endfor@\cr @unfill@ $z_5'\to z_4'\to z_1'\to z_3'\to z_6'\to\cycle$.\cr \enddisplay \ansno4.7: ${1\over2}\bigl["North",{1\over2}["North","West"]\bigr]= {1\over2}\bigl[90,{1\over2}[90,180]\bigr]={1\over2}[90,135]=112.5$. \ansno4.8: $30^\circ$, $60^\circ$, $210^\circ$, and $240^\circ$. Since it's possible to add or subtract $360^\circ$ without changing the meaning, the answers $-330^\circ$, $-300^\circ$, $-150^\circ$, and $-120^\circ$ are also correct. \ansno4.9: $z_{1l}=(25,30)$, $z_{1r}=(25,20)$. \ansno4.10: He said `@penstroke@ $z_{1e}\{"up"\}\to z_{2e}\{"left"\}\to z_{3e}\{"down"\} \to z_{4e}\{"right"\}\to\cycle$'. \ansno4.11: We use angles ^{perpendicular} to $(w,h)$ and $(w,-h)$ at the diagonal endpoints: \begindisplay $x_{1l}=x_{4l}=0$;\cr $x_2=x_5=.5w$;\cr $x_{3r}=x_{6r}=w$;\cr $y_{1r}=y_2=y_{3l}=h$;\cr $y_{4r}=y_5=y_{6l}=0$;\cr $z_{1'}=.25[z_1,z_6]$; \ $z_{6'}=.75[z_1,z_6]$;\cr $theta_1:=\angle(w,-h)+90$;\cr $\penpos1(b,theta_1)$; \ $\penpos6(b,theta_1)$;\cr $z_7=.5[z_1,z_6]$; \ $\penpos7(.6b,theta_1)$;\cr $\penpos{1'}(b,theta_1)$; \ $\penpos{6'}(b,theta_1)$;\cr @penstroke@ $z_{1e}\to z_{1'e}\{z_{6'}-z_{1'}\}\to z_{7e}\to \{z_{6'}-z_{1'}\}z_{6'e}\to z_{6e}$;\cr $z_{3'}=.25[z_3,z_4]$; \ $z_{4'}=.75[z_3,z_4]$;\cr $theta_3:=\angle(-w,-h)+90$;\cr $\penpos3(b,theta_3)$; \ $\penpos4(b,theta_3)$;\cr $z_8=.5[z_1,z_6]$; \ $\penpos8(.6b,theta_3)$;\cr $\penpos{3'}(b,theta_3)$; \ $\penpos{4'}(b,theta_3)$;\cr @penstroke@ $z_{3e}\to z_{3'e}\{z_{4'}-z_{3'}\}\to z_{8e}\to \{z_{4'}-z_{3'}\}z_{4'e}\to z_{4e}$;\cr $\penpos2(b,0)$; \ $\penpos5(b,0)$; \ @penstroke@ $z_{2e}\to z_{5e}$.\cr \enddisplay \ansno5.1: The width is |0.8em#|, and an |em#| is 10 true points, so the box will be exactly $8\pt$ wide in device-independent units. The height will be $7\pt$. \ (And the depth below the baseline will be $0\pt$.) \ansno5.2: $8\times3.6=28.8$ rounds to the value $w=29$; similarly, $h=25$. \ (And $d=0$.) \ansno5.3: Here's one way, using a variable "slab" to control the \rightfig A5a ({200\apspix} x 252\apspix) ^-71pt ^^{S} pen breadth at the ends of the stroke: \begintt slab#:=.8pt#; define_blacker_pixels(slab); beginchar("S",5/9em#,cap#,0); "The letter S"; penpos1(slab,70); penpos2(.5slab,80); penpos3(.5[slab,thick],200); penpos5(.5[slab,thick],210); penpos6(.7slab,80); penpos7(.25[slab,thick],72); x1=x5; y1r=.94h+o; x2=x4=x6=.5w; y2r=h+o; y4=.54h; y6l=-o; x3r=.04em; y3=.5[y4,y2]; x5l=w-.03em; y5=.5[y4,y6]; .5[x7l,x7]=.04em; y7l=.12h-o; path trial; trial=z3{down}..z4..{down}z5; pair dz; dz=direction 1 of trial; penpos4(thick,angle dz-90); penstroke z1e..z2e{left}..z3e{down} ..z4e{dz}..z5e{down}..z6e{left}..z7e; penlabels(1,2,3,4,5,6,7); endchar; \endtt Notice that the pen angle at point 4 has been found by letting \MF\ ^^{direction} construct a ^{trial path} through the center points, then using the ^{perpendicular} direction. The letters work reasonably well at their true size: `{\manual\IOS\IOO} {\manual\IOI\IOO} {\manual\IOI\IOS} {\manual\IOI\IOS\IOI\IOS}.' \ansno5.4: After an ``isolated expression,'' \MF\ thinks it is at the end of a statement or command, so it expects to see a semicolon next. You should type, e.g., `|I;|~|mode_setup|' to keep \MF\ happy. \ansno5.5: Yes. \ansno6.1: (a) No, the second token represents $1\over65536$. \ (A token has the same meaning as~`|0|' ^^{zero} if and only if its decimal value is strictly less than $2^{-17}=.00000\,76293\,94531\,25$.) \ (b)~Yes; both tokens represent $1\over65536$, because 1~is the nearest integer to both $.00001\times65536=.65536$ and $0.00002\times65536=1.31072$. \ (c)~No, |0.00003| represents $2\over65536$. \ (d)~Yes, they both mean ``^{enormous number} that needs to be reduced''; \MF\ complains in both cases and substitutes the largest legal numeric token. \ (Rounding 4095.999999 to the nearest multiple of $1\over65536$ yields 4096, which is too big.) \ansno6.2: \cstok{xx}, \cstok{3.1} (a numeric token), \cstok{.6} (another numeric token), \cstok{..}, \cstok{[[}, \cstok{a}, \cstok{+-}, \cstok{bc\_d}, \cstok{e}, \cstok{]}, \cstok{]}, \chardef\"=`\"\cstok{\"a \%\"} (a string token), \cstok{<\|>}, \cstok{(} (see rule~5), \cstok{(}, \cstok{\$}, \cstok{1} (a numeric token), \cstok{5} (likewise numeric), \cstok{\"+-\"} (a string token), and \cstok{\"\"} (a string token that denotes an empty sequence of characters). All of these tokens are symbolic unless otherwise mentioned. \ (Notice that four of the spaces and two of the periods were deleted by rule~1. One way to verify that \MF\ finds precisely these tokens is to prepare a test file that says `|isolated| |expression;|' on its first line and that contains the stated text on its second line. Then respond to \MF's error message by repeatedly typing `|1|', so that one token is deleted at a time.) \ansno6.3: The statement is basically true but potentially misleading. You can insert any number of spaces {\sl between\/} tokens without changing the meaning of a program, but you cannot insert a space in the {\sl middle\/} of any token without changing something. You can delete spaces between tokens {\sl unless\/} that would ``glue'' two adjacent tokens together. \ansno6.4: False. It may seem that this new sort of numeric token would be recognized only in cases where the period is not followed by a digit, hence the period would be dropped anyway by rule~1. However, the new rule would have disastrous consequences in a line like `|draw| |z1..z2|'! \ansno7.1: You can put a space between the subscripts, as in `|a1|~|5|'. \ (We'll see later that a ^{backslash} acts as a null symbol, hence `|a1\5|' is another solution.) \ansno7.2: No; |a[-1]| can't be accessed without using |[| and |]|. The only other form of \<subscript> is \<numeric token>, which can't be negative. \ (Well, strictly speaking, you could say `|let|~|?=[;| |let|~|??=]|' and then refer to `|a?-1??|'; but that's cheating.) \ansno7.3: Assuming that `|+|' was still a spark when he said `|let|~|plus=+|', he can't refer to the variable `|a.plus1|' unless he changes the meaning of |plus| again to make it a~tag. \ (We will eventually learn a way to do this without permanently clobbering |plus|, as follows: `^|begingroup| ^|save| |plus;| |a.plus1| ^|endgroup|'.) \ansno7.4: True. \ (But a \<suffix> is not always a \<variable>.) \ansno7.5: Yes, because it removes any existing value that $x$ may have had, of whatever type; otherwise you couldn't safely use $x$ in a numeric equation. It's wise to declare numeric variables when you're not sure about their former status, and when you're sure that you don't care what their previous value was. A numeric declaration together with a comment also provides useful documentation. \ (Incidentally, `|numeric|~|x|' doesn't affect other variables like `|x2|' or `|x.x|' that might be present.) \ansno7.6: (a)~The `|42|' is illegal because subscripts must be collective. \ (b)~The `|24|' is illegal because a \<declared variable> must start with a \<symbolic token>, not a numeric token. \ (c)~There's nothing wrong with the consecutive commas; the second comma begins a \<declared variable>, so it loses its former meaning and becomes a tag. Thus \MF\ tries to declare the variable `|,t,path|'. However, `|path|' cannot appear in a suffix, since it's a spark. \ (Yes, this is admittedly tricky. Computers follow rules.) \ansno8.1: |((z1+z2)..((z3/4)*5))..(z6-(7*(8z9)))|. \ansno8.2: The fraction |100/3| is evaluated first (because such divisions take precedence); the rounding error in this fraction is then magnified by~100. \ansno8.3: A |sqrt| takes precedence over any operation with two operands, hence the machine computes `|(sqrt|~|2)**2|'; \MF\ was somewhat lucky that the answer turned out to be exactly~2. \ (The |sqrt| operation computes the nearest multiple of $1\over65536$, and the rounding error in this quantity is magnified when it is squared. If you try |sqrt|~|3**2|, you'll get |3.00002|; also |sqrt|~|2**4| turns out to be |4.00002|.) \ Incidentally, the ^|**| operation of plain \MF\ has the same precedence as |*| and~|/|; hence `|x*y**2|' means the same as `|(x*y)**2|', and `|-x**2|' means `|(-x)**2|', contrary to the conventions of {\eightrm ^{FORTRAN}}. \ansno8.4: Since `^@or@' has stronger precedence than `$<$' or `$>$', ^^|<| ^^|>| \MF\thinspace\ tries to evaluate this expression by putting things in parentheses as follows: `$(0>(1\mathbin{\bf or}a))<a$'. Now `$1\mathbin{\bf or}a$' makes no sense, because `@or@' operates only on booleans; in such cases \MF\ uses the right operand~`$a$' as the result. Then `$\mkern1mu0>a$' is indeterminate because $a$~is unknown; \MF\ treats this as false. Finally `${\rm false}<a$' is another illegal combination of types. \ansno8.5: The token `|++-|' is undefined, so it is a tag; therefore |++-7| is a subscripted variable, which was multiplied by zero. \ansno8.6: The associative law is valid for exact computations, but not for rounded computations. For example, it fails even in the case of multiplication, since $(.1\ast.1)\ast10=0.09995$ while $.1\ast(.1\ast10)=.1$ when products are rounded to the nearest multiples of $1\over65536$. However, this observation doesn't quite explain the stated example, which would have yielded 7 in all cases if \MF\ had computed $2\pyth+4$ with full accuracy! The closest approximation to $\sqrt{20}$ is ^^{accuracy} $4{30942\over65536}$, but $2\pyth+4$ turns out to be $4{30941\over65536}$ instead. \MF\ computes the absolutely best possible approximations to the true answers when it does multiplications, divisions, and square roots, but not when it does Pythagorean operations. \ansno8.7: It's impossible to make an expression from `\<numeric token> \<numeric token>', because the rule for \<scalar multiplication operator> specifically prohibits this. \MF\ will recognize the first `|2|' as a \<numeric primary>, which is ultimately regarded as a \<numeric expression>; the other `|2|' will probably be an extra token that is flushed away after an error message has been given. \ansno8.8: If a numeric token is followed by `|/|\<numeric token>' but not preceded by `\<numeric token>|/|', the syntax allows it to become part of an expression only by using the first case of \<numeric token primary>. Therefore `|1/2/3/4|' must be treated as `|(1/2)/(3/4)|', and `|a/2/3/4|' must be treated as `|a/(2/3)/4|'. \ansno8.9: \<string primary>\is\<string variable>\parbreak \qquad\alt\<string token>\parbreak \def\\#1{\thinspace{\tt#1}\thinspace}% \qquad\alt\\(\<string expression>\\)\parbreak \qquad\alt\\{substring}\<pair expression>\\{of}\<string primary>\parbreak \<string secondary>\is\<string primary>\parbreak \<string tertiary>\is\<string secondary>\parbreak \<string expression>\is\<string tertiary>\parbreak \qquad\alt\<string expression>\\{\char`\&}\<string tertiary>\par \medskip\noindent (The full syntax in Chapter~25 includes several more varieties of \<string primary> that haven't been hinted at yet.) \ansno9.1: (a)~Point 1 should lie nine pixels to the left of point~7, considering horizontal positions only; no information is given about the vertical positions $y_1$ or $y_7$. \ (b)~Point~7 should sit directly above or below point~4, and its distance up from the baseline should be halfway between that of points 4 and~5. \ (c)~The left edge of the currently-picked-up pen, when that pen is centered at point~21, should be one pixel to the right of its right edge when at point~20. \ (Thus there should be one clear pixel of white space between the images of the pen at points 20 and~21.) \ansno9.2: (a) $y_{13}=-y_{11}$ (or $-y_{13}=y_{11}$, or $y_{13}+y_{11}=0$). \ (b)~$z_{10}=z_{12}+("mm",-1)$. \ (c)~$z_{43}={1\over3}[(0,h),(w,-d)]$. \ansno9.3: (a) $z_1=z_2=z_3=(w,h)$; $z_4=z_5=z_6=(0,0)$. \ (b)~$z_1=z_6=(.5w,.5h)$; $z_2=(.75w,.75h)$; $z_3=(w,h)$; $z_4=(0,0)$; $z_5=(.25w,.25h)$. \ansno9.4: $z="whatever"[z_1,z_2]$; $z="whatever"[z_3,z_4]$. \ (Incidentally, it's interesting to watch this computation in action. Run \MF\ with |\tracingequations:=|\allowbreak|tracingonline:=1| and say, for example, \begintt z=whatever[(1,5),(8,19)]; z=whatever[(0,17),(6,1)]; \endtt the solution appears as if by magic. If you use |alpha| and |beta| in place of the whatevers, the machine will also calculate values for "alpha" and "beta".) \ansno9.5: $z="whatever"[z_1,z_2]$; $z-z_3="whatever"\ast(z_5-z_4)$. \ansno9.6: $z_{11}-z_{12}="whatever"\ast(z_{13}-z_{14})$ ^{rotated} 90, assuming that $z_{13}-z_{14}$ is known. \ (It's also possible to say `$(z_{11}-z_{12})\mathbin{\rm dotprod} (z_{13}-z_{14})=0$', ^^{dotprod} although this risks overflow if the coordinates are large.) \ansno9.7: One solution constructs the point $z_4$ on $z_2\to z_3$ such that $z_4\to z_1$ is perpendicular to $z_2\to z_3$, using ideas like those in the previous two exercises: `$z_4="whatever"[z_2,z_3]$; $z_4-z_1="whatever"\ast(z_3-z_2)$ rotated 90'. Then the requested distance ^^{abs} ^^{ypart} is $length(z_4-z_1)$. But there's a slicker solution: Just calculate $$\hbox{abs ypart$((z_1-z_2)\mathbin{\rm rotated}-angle(z_3-z_2))$.}$$ \ansno9.8: It would be nice to say simply `$z="whatever"[z_2,z_3]$' and then to be able to say either `length$(z-z_1)=l$' or `$z-z_1=(l,0)$ rotated "whatever"'; but neither of the second equations is legal. \ (Indeed, there couldn't possibly be a legal solution that has this general flavor, because any such solution would determine a unique $z$, while there are two points to be determined.) \ The best way seems to be to compute $z_4$ as in the previous exercise, ^^{pythagorean subtraction} and then to let $v=(l\mathbin{+{-}+}\mathop{\rm length} (z_4-z_1))\ast\mathop{\rm unitvector}(z_3-z_2)$; ^^{unitvector} ^^{length} the desired points are then $z_4+v$ and $z_4-v$. \ansno9.9: Such an equation tells us nothing new about $a$ or $b$. Indeed, each use of "whatever" introduces a new independent variable, and each new independent variable ``uses up'' one equation, since we need $n$ equations to determine the values of $n$~unknowns. On the other hand an equation between pairs counts as two equations; so there's a net gain of one, when "whatever" appears in an equation between pairs. \ansno10.1: Yes, but it must be done in two steps: `@numeric@ "newcode"; $"newcode"="code"+1$; @numeric@ "code"; $"code"="newcode"$'. \ansno10.2: The assignment `$x_3:=\null$^"whatever"' does exactly what you want. \ansno10.3: The result shows that $s_1=s_3=s_4$ and $s_2=s_5=s_6$ now: \begintt s[]=unknown string s1=unknown string s3 s2=unknown string s6 s3=unknown string s4 s4=unknown string s1 s5=unknown string s2 s6=unknown string s5 \endtt (The assignment $s_2:=s_5$ broke $s_2$'s former relationship with $s_1$, $s_3$, and $s_4$.) \ansno10.4: The results are \begindisplay |## a=1|\cr |## a=b+1|&(after the first assignment)\cr |## b=0.5a-0.5|&(after the second assignment)\cr |### -1.5a=-%CAPSULEnnnn-0.5|&(after the third assignment)\cr |>> a|&(after `@show@'; variable $a$ is independent)\cr |>> 0.33333a-0.33333|&(this is the final value of $b$)\cr \enddisplay ^^|CAPSULE| Let $a_k$ denote the value of $a$ after $k$ assignments were made. Thus, $a_0=1$, and $a_1$ was dependent on the independent variable~$b$. Then $a_1$ was discarded and $b$ became dependent on the independent variable~$a_2$. The right-hand side of the third assignment was therefore $a_2+b$. At the time $a_2$ was about to be discarded, \MF\ had two dependencies $b=0.5a_2-0.5$ and $\kappa=1.5a_2-0.5$, where $\kappa$ was a nameless ``^{capsule}'' inside of the computer, representing the new value to be assigned. Since $\kappa$ had a higher coefficient of dependency than~$b$, \MF\ chose to make $\kappa$ an independent variable, after which $-1.5a_2$ was replaced by $-\kappa-0.5$ in all dependencies; hence $b$ was equal to $0.33333\kappa-0.33333$. After the third assignment was finished, $\kappa$ disappeared and $a_3$ became independent in its place. \ (There's a 50-50 chance that the line `|##| |a=%CAPSULEnnnn|' was also printed after the third assignment; this means that $a$ was temporarily dependent on $\kappa$, before $\kappa$ was discarded. If the equation $a=\kappa$ happened to make $\kappa$ dependent on~$a$, rather than vice versa, no ^^{hash hash} `|##|' line was printed; such lines are omitted when a capsule or part of a capsule has been made dependent, unless you have made ^"tracingcapsules"$\null>0$.) \ansno11.1: Almost, but not quite. The values of standard dimension variables like "pt" and "mm" will be identical in both setups, as will the values of ad~hoc dimension variables like "em" and "x\_height". But pen-oriented dimensions that are defined via @define\_blacker\_pixels@ will be slightly different, because "cheapo" mode has $"blacker"=0.65$ while "luxo" mode has $"blacker"=0.1$ (since the "luxo" printer has different physical characteristics). Similarly, @define\_corrected\_pixels@ (which we are just about to discuss) will produce slightly different results in the two given modes. \ansno11.2: Increasing $"ht"\0$ would make the letter shape and the bounding box taller; increasing $"xgap"\0$ would move point~5 to the left, thereby making the middle bar shorter; increasing $u\0$ would make the shape and its bounding box wider; increasing $s\0$ would widen the bounding box at both sides without changing the letter shape; increasing $o\0$ would move points 4,~5, and~6 to the right; increasing $"px"\0$ would make the pen thicker (preserving the top edge of the upper bar, the bottom edge of the lower bar, and the center of the middle bar and the stem). \ansno11.3: The only possible surprise is the position of $y_1$, which should match similar details in the `{\manual h}' and the~`\kern1pt{\manual j}\kern1pt' of Chapter~4: \begintt beginchar("F",14*u#+2s#,ht#,0); pickup logo_pen; x1=x2=x3=leftstemloc; x4=w-x1+o; x5=x4-xgap; y2=y5; y3=y4; bot y1=-o; top y3=h; y2=barheight; draw z1--z3--z4; draw z2--z5; labels(1,2,3,4,5); endchar; \endtt \ansno11.4: The quantity called "ss" in Chapter~4 is now "leftstemloc". \begintt beginchar("M",18*u#+2s#,ht#,0); pickup logo_pen; x1=x2=leftstemloc; x4=x5=w-x1; x3=w-x3; y1=y5; y2=y4; bot y1=-o; top y2=h+o; y3=y1+ygap; draw z1--z2--z3--z4--z5; labels(1,2,3,4,5); endchar;|smallskip beginchar("T",13*u#+2s#,ht#,0); pickup logo_pen; lft x1=0; x2=w-x1; x3=x4=.5w; y1=y2=y3; top y1=h; bot y4=-o; draw z1--z2; draw z3--z4; labels(1,2,3,4); endchar; \endtt \ansno11.5: `{\manual nmnkjmnihinj\/}'; possibly also `{\manual hijklmmjnmji}'; and Georgia ^{Tobin} suggests that `{\manual knjiinlimllhinj\/}' might be a legal term. \ansno11.6: Delete the line of |logo.mf| that defines |barheight#|, and insert that line into each of the parameter files |logo10.mf|, |logo9.mf|, |logo8.mf|. Then other bar-line heights are possible by providing new parameter files; another degree of ``meta-ness'' has therefore been added to the meta-font. \ansno11.7: (This is tricky.) \ Insert the lines \begintt if known pixmag: begingroup interim hppp:=pixmag*hppp; special "title cheapo simulation" endgroup; extra_endchar:="currentpicture:=currentpicture scaled pixmag;" & "w:=w*pixmag;" & extra_endchar; fi \endtt right after `|mode_setup|' in |logo.mf|, and also include the line \begintt if known pixmag: hppp:=pixmag*hppp; vppp:=pixmag*vppp; fi \endtt at the very end of that file. Then run \MF\ with \begintt \mode="cheapo"; input cheaplogo10 \endtt where the file `|cheaplogo10.mf|' says simply `|pixmag=10;| |input| |logo10|'. \ (The interim "hppp" setting and the ^@special@ command are used to fool \MF\ into giving the appropriate extension to the ^|gf| file name. Incidentally, you could print with this font on "cheapo" at ten-fold magnification if you told \TeX\ to use the font `|cheaplogo10| |scaled| |10000|'; but on "luxo" you would simply call this font `|cheaplogo10|'.) \ansno12.1: The changes are straightforward, except for the italic correction (for which a rough estimate like the one shown here is good enough): \def\xs(#1,#2){\{(z_{#1}-z_{#2})\,{\rm xscaled}\,3\}}% \begindisplay |"Right parenthesis"|;\cr @numeric@ $"ht"\0,"dp"\0$; \ $"ht"\0="body\_height"$; \ $.5["ht"\0,-"dp"\0]="axis"\0$;\cr @beginchar@\kern1pt(|")"|$,7u\0,"ht"\0,"dp"\0)$; \ @italcorr@ $"axis"\0\ast"slant"-.5u\0$;\cr @pickup@ "fine.nib"; \ $\penpos1("hair"-"fine",0)$;\cr $\penpos2(.75["thin","thick"]-"fine",0)$; \ $\penpos3("hair"-"fine",0)$;\cr $\mathop{"lft"}x_{1l}=\mathop{"lft"}x_{3l}=u$; \ $\mathop{"rt"}x_{2r}=x_1+4u$; \ $\mathop{"top"}y_1=h$; \ $y_2=.5[y_1,y_3]="axis"$;\cr @filldraw@ $z_{1l}\xs(2l,1l)\ldots z_{2l}\ldots\xs(3l,2l)z_{3l}$\cr \qquad$\dashto z_{3r}\xs(2r,3r) \ldots z_{2r}\ldots\xs(1r,2r)z_{1r}\dashto\cycle$;\cr @penlabels@$(1,2,3)$; \ @endchar@;\cr \enddisplay We will see in Chapter 15 that it's possible to guarantee perfect symmetry between left and right parentheses by using picture transformations. \ansno12.2: When horizontal lines are being typeset, \TeX\ keeps track of the maximum height and maximum depth of all boxes on the line; this determines whether or not extra space is needed between baselines. The height and depth are also used to position an accent above or below a character, and to place symbols in mathematical formulas. Sometimes boxes are also stacked~up vertically, in which case their heights and depths are just as important as their widths are for horizontal setting. \ansno13.1: $(4,4)$, $(4,5)$, $(5,5)$, $(5,4)$. \ (Therefore the command \begindisplay @unfill@ $(4,4)\dashto(4,5)\dashto(5,5)\dashto(5,4)\dashto\cycle$ \enddisplay will decrease the value of this pixel by 1.) \ansno13.2: The result would be exactly the same; @fill@ and @unfill@ commands can be given in any order. \ (After an initial @unfill@ command, some pixel values will be $-1$, the others will be zero.) \ansno13.3: @unfill@ $(4,1)\dashto(4,8)\dashto(5,8)\dashto(5,1)\dashto\cycle$. \ansno13.4: Here are two of the many solutions: \begindisplay @fill@ $(0,3)\dashto(9,3)\dashto(9,6)\dashto(6,6)\dashto(6,9)\dashto$\cr \indent $(3,9)\dashto(3,0)\dashto(6,0)\dashto(6,6)\dashto(0,6)\dashto\cycle$;\cr @fill@ $(0,3)\dashto(9,3)\dashto(9,6)\dashto(0,6)\dashto(0,3)\dashto$\cr \indent $(3,3)\dashto(3,0)\dashto(6,0)\dashto(6,9)\dashto(3,9)\dashto (3,3)\dashto\cycle$.\cr \enddisplay (It turns out that {\sl any\/} pixel pattern can be obtained by a single, sufficiently hairy @fill@ command. But unnatural commands are usually also inefficient and unreadable.) \ansno13.5: The value of the enclosed pixel is increased by 2. \ (We'll see later that there's a simpler way to do this.) \ansno13.6: True; $j-k=l-m$, since $k+l=j+m$. \ (What comes up must go down.) \ansno13.7: The tricky part is to remember that `@erase@ @draw@ $z_i\dashto z_j$' will erase pixels near $z_i$ and $z_j$. Therefore if $z_3\dashto z_4$ is drawn before $z_4\dashto z_2$, we can't erase $z_4\dashto z_2$ without losing some of $z_3\dashto z_4$; it's necessary to erase only part of one line. One way to solve the problem is to do the following, after defining the points and picking up the pen as before: \begindisplay @draw@ $z_3\dashto z_4$; \ @draw@ $z_5\dashto z_6$;\cr ^@cullit@; \ \pickup @pencircle@ scaled $1.6"pt"$;\cr ^@undraw@ $z_7\dashto {1\over2}[z_7,z_5]$; \ @undraw@ $z_2\dashto {1\over2}[z_2,z_4]$;\cr @cullit@; \ \pickup @pencircle@ scaled $.4"pt"$;\cr @draw@ $z_3\dashto z_1\dashto z_2\dashto z_4$; \ @draw@ $z_5\dashto z_7\dashto z_8\dashto z_6$;\cr @for@ $k=1$ @upto@ 4: \ @draw@ $z_k\dashto z_{k+4}$; \ @endfor@.\cr \enddisplay (Note that it would not be quite enough to erase only from $z_7$ to ${1\over3}[z_7,z_5]$!)\par It's also possible to solve this problem without partial erasing, if we use additional features of \MF\ that haven't been explained yet. Let's consider only the job of drawing $z_7\dashto z_5\dashto z_6$ and $z_3\dashto z_4\dashto z_2$, since the other eight lines can easily be added later. Alternative Solution~1 uses picture operations: \begindisplay @pen@ "eraser"; \ $"eraser"=@pencircle@$ scaled $1.6"pt"$;\cr @draw@ $z_3\dashto z_4$; \ @erase@ @draw@ $z_7\dashto z_5$ ^@withpen@ "eraser"; \ @draw@ $z_7\dashto z_5$;\cr @picture@ "savedpicture"; \ $"savedpicture"="currentpicture"$; \ ^@clearit@;\cr @draw@ $z_6\dashto z_5$; \ @erase@ @draw@ $z_2\dashto z_4$ ^@withpen@ "eraser"; \ @draw@ $z_2\dashto z_4$;\cr ^@addto@ "currentpicture" @also@ "savedpicture".\cr \enddisplay Alternative Solution 2 is trickier, but still instructive; it uses `^@withweight@' options and the fact that @draw@ does not increase any pixel values by more than the stated weight when the path is a straight line: \begindisplay @draw@ $z_3\dashto z_4$; \ ^@undraw@ $z_7\dashto z_5$ @withpen@ "eraser";\cr @draw@ $z_7\dashto z_5$ @withweight@ 2; \ ^@cullit@ @withweight@ 2;\cr @draw@ $z_6\dashto z_5$; \ ^@undraw@ $z_2\dashto z_4$ @withpen@ "eraser";\cr @draw@ $z_2\dashto z_4$ @withweight@ 2;\cr \enddisplay (These alternative solutions were suggested by Bruce ^{Leban}.) \ansno13.8: Here's an analog of the first solution to the previous exercise: \begindisplay @beginchar@\kern1pt(|"*"|$,10"pt"\0,7"pt"\0,2"pt"\0)$;\cr @pair@ "center"; \dots \<as in the hint>\cr \pickup @pencircle@ scaled $.4"pt"$; \ @draw@ "star";\cr @cullit@; \ \pickup @pencircle@ scaled $1.6"pt"$;\cr @for@ $k=0$ @upto@ 4: \ @undraw@ subpath$(k+.55,k+.7)$ @of@ "star"; \ @endfor@\cr @cullit@; \ \pickup @pencircle@ scaled $.4"pt"$;\cr @for@ $k=0$ @upto@ 4: \ @draw@ subpath$(k+.47,k+.8)$ @of@ "star"; \ @endfor@\cr @labels@(0,1,2,3,4); \ @endchar@.\cr \enddisplay However, as in the previous case, there's an Alternate Solution~1 by Bruce ^{Leban} that is preferable because it doesn't depend on magic constants like .55 and~.47: \begindisplay @beginchar@ $\ldots$ \<as above> $\ldots$ scaled $.4"pt"$;\cr @picture@ "savedpicture"; \ $"savedpicture"=@nullpicture@$;\cr @pen@ "eraser"; \ $"eraser":=@pencircle@$ scaled $1.6"pt"$;\cr @for@ $k=0$ @upto@ 4:\cr \indent @draw@ subpath$(k,k+1)$ @of@ "star"; @cullit@;\cr \indent @undraw@ subpath$(k+3,k+4)$ @of@ "star" @withpen@ "eraser"; @cullit@;\cr \indent @addto@ "savedpicture" @also@ "currentpicture"; @clearit@; @endfor@\cr $"currentpicture":="savedpicture"$; \ @labels@(0,1,2,3,4); \ @endchar@.\cr \enddisplay \ansno13.9: It increases pixel values by 1 in the five lobes of the star, and by~2 in the central pentagon-like region. \ansno13.10: @def@ @overdraw@ @expr@ $c$ = @erase@ @fill@ $c$; @draw@ $c$ @enddef@. \ansno13.11: First we need to generalize the ^@overdraw@ macro of the previous exercise so that it applies to arbitrary cycles~$c$, even those that are self-intersecting: \begindisplay @def@ @overdraw@ @expr@ $c$ = ^@begingroup@\cr \indent@picture@ "region"; $"region":=@nullpicture@$;\cr \indent^@interim@ $"turningcheck":=0$; ^@addto@ "region" @contour@ $c$;\cr \indent^@cull@ "region" @dropping@ $(0,0)$;\cr \indent^@cullit@; @addto@ "currentpicture" ^@also@ $-"region"$; @cullit@;\cr \indent@draw@ $c$ ^@endgroup@ @enddef@;\cr \enddisplay (This code uses operations defined later in this chapter; it erases the "region" of pixels that would be made nonzero by the command `@fill@~$c$'.) \ The watchband is now formed by overdrawing its links, one at a time, doing first the ones that are underneath: \begindisplay @beginchar@$("M",1.25"in"\0,.5"in"\0,0)$; \ \pickup @pencircle@ scaled .4"pt";\cr $z_1=(20,-13)$; \ $z_2=(30,-6)$; \ $z_3=(20,1)$; $z_4=(4,-7)$;\cr \indent $z_5=(-12,-13)$; \ $z_6=(-24,-4)$; \ $z_7=(-15,6)$;\cr @path@ $M$; $M=("origin"\to z1\to z2\to z3\to z4\to z5\to z6\to z7\to$\cr \indent$"origin"\to -z7\to -z6\to -z5\to -z4\to -z3\to -z2\to -z1\to\cycle)$\cr ^^"origin" \indent\indent scaled $(h/26)$ shifted $(.5w,.5h)$;\cr @def@ @link@(@expr@ $n$) =\cr \indent @overdraw@ subpath ${1\over3}(n,n+1)$ of $M\;\dashto$\cr \indent\indent subpath ${1\over3}(n+25,n+24)$ of $M\;\dashto\;\cycle\;$ @enddef@;\cr @for@ $k=1$ @upto@ 12: @link@$(k+11)$; @link@$(12-k)$; @endfor@ @endchar@;\cr \enddisplay \ansno13.12: The pixel pattern $\pixpat1121$ is culled to $\pixpat1111\,$, and \MF\ needs to sort the edges as it does this; so the result is simply \begintt row 1: || 0+ 2- row 0: || 0+ 2- \endtt \ansno13.13: The pixel pattern is $\pixpat1121+\pixpat1121+\pixpat1112-\pixpat2111 =\pixpat1243$ before the final rotation, with the reference point at the lower left corner of the~4; after rotation it is $\pixpat2314\,$, with the reference point at the lower {\sl right\/} corner of the~4. Rotation causes \MF\ to sort the edges, but the transition values per edge are never more than $\pm3$. You weren't expected to know about this limit of $\pm3$, but it accounts for what is actually reported: \begintt row 1: || -2++ -1+ 0--- row 0: || -2+ -1+++ 0--- 0- \endtt \ansno13.14: `|V| |scaled-1|' should be the same as `|V| |rotated| |180|', because transformations apply to coordinates rather than to pixel values. \ (Note, incidentally, that the reflections `|V|~^|xscaled-1|' and `|V|~^|yscaled-1|' both work, and that `|V|~|scaled-1|' is the same as `|V|~|xscaled-1| |yscaled-1|'.) \ansno13.15: The result is the same as `|V| |shifted| |(2,3)|'; the coordinates of a shift are rounded to the nearest integers when a picture is being shifted. \ansno13.16: |row 3: 0+ 4- |\|\parbreak |row 2: 0+ 4- |\|\parbreak |row 1: 0+ 4- 0+ 2- |\|\parbreak |row 0: 0+ 4- 0+ 2- |\|\par\nobreak \smallskip\noindent (Scaling of pictures must be by an integer.) \ansno13.17: \MF\ is currently executing instructions after having read as far as line~5 of the file |expr.mf|. \ansno13.18: The pixel values of "currentpicture" become 1 if they were $\pm1$, otherwise they become~0. \ansno13.19: (a) @addto@ $V_1$ @also@ $V_2$; @cull@ $V_1$ @keeping@ $(2,2)$. \ (b) Same, but cull keeping $(1,2)$. \ (c)~Same, but cull keeping $(1,1)$. \ansno13.20: Subtract one from the other, and cull the result dropping $(0,0)$; then test to see if the total weight is zero. \ansno13.21: (a)~Same as `@draw@ $p$', but using $q$ instead of the currently-picked-up pen. \ (b)~Same effect as `@draw@~$p$; @draw@~$p$; @draw@~$p$' (but faster). \ (c)~Same as `@draw@~$p$ @withweight@~$w$', because @undraw@'s `@withweight@~$-1$' is overridden. \ (d)~Same as `@unfilldraw@~$c$; @unfilldraw@~$c$', but using $q$ instead of "currentpen". \ (e)~Same as `@erase@ @filldraw@~$c$', because the `@withweight@~2' is overridden. \ [Since @erase@ has culled all weights to 0 or~1, there's no need to ``doubly erase.''] \ (f)~Same effect as `@cullit@; @addto@ "currentpicture" @also@ "currentpicture"' (but faster). \ansno13.22: @vardef@ @safefill@ @expr@ $c$ $=$ ^@save@ "region";\parbreak \quad@picture@ "region"; "region"=@nullpicture@;\parbreak \quad^@interim@ ^"turningcheck"$\null:=0$;\parbreak \quad @addto@ "region" @contour@ $c$; \ @cull@ "region" @dropping@ $(0,0)$;\parbreak \quad @addto@ "currentpicture" @also@ "region" @enddef@. \ansno13.23: @cull@ "currentpicture" @keeping@ $(1,"infinity")$;\parbreak @picture@ $v$; \ $v:="currentpicture"$;\parbreak @cull@ "currentpicture" @keeping@ $(1,1)$ @withweight@ 3;\parbreak @addto@ "currentpicture" @also@ $v\;-\;v$ shifted "right"\parbreak \qquad $\null-\;v$ shifted "left" $\null-\;v$ shifted "up" $\null-\;v$ shifted "down";\parbreak @cull@ "currentpicture" @keeping@ $(1,4)$. \ansno13.24: (We assume that "currentpicture" initially has some configuration in which all pixel values are zero or one; one means ``alive.'') \begindisplay @picture@ $v$; @def@ "c" $=$ "currentpicture" @enddef@;\cr @forever@: \ $v:=c$; \ @showit@;\cr \quad @addto@ $c$ @also@ $c$ shifted "left" $+$ "c" shifted "right";\cr \quad @addto@ $c$ @also@ $c$ shifted "up" $+$ "c" shifted "down";\cr \quad @addto@ $c$ @also@ $c-v$; \ @cull@ $c$ @keeping@ $(5,7)$; \ @endfor@.\cr \enddisplay (It is wise not to waste too much computer time watching this program.) \ansno14.1: @beginchar@\kern1pt(|"b"|$,5"pt"\0,5"pt"\0,0)$;\parbreak @fill@ $((0,0)\dashto"quartercircle"\dashto{\rm cycle})$ scaled 10"pt"; \ @endchar@. \ansno14.2: A "quartercircle" corresponds to a circle whose diameter is~1; the radius is~$1\over2$. \ansno14.3: @beginchar@\kern1pt(|"c"|$,5"pt"\0,5"pt"\0,0)$;\parbreak @pickup@ @pencircle@ scaled $(.4"pt"+"blacker")$;\parbreak @draw@ "quartercircle" rotated 90 scaled 10"pt" shifted $(5"pt",0)$; \ @endchar@. \ansno14.4: @beginchar@\kern1pt(|"d"|$,5"pt"\0\ast\rmsqrt2,5"pt"\0,0)$;\parbreak @pickup@ @pencircle@ scaled $(.4"pt"+"blacker")$;\parbreak @draw@ $((0,0)\dashto"quartercircle"\dashto{\rm cycle})$ rotated 45 scaled 10"pt" shifted $(.5w,0)$;\parbreak @endchar@. \ansno14.5: @beginchar@\kern1pt(|"e"|$,10"pt"\0,7.5"pt"\0,2.5"pt"\0)$;\parbreak @pickup@ @pencircle@ scaled $(.4"pt"+"blacker")$;\parbreak @for@ $D=.2w,.6w,w$: \ @draw@ "fullcircle" scaled $D$ shifted $(.5w,.5[-d,h])$;\parbreak @endfor@ @endchar@. \par\medskip\noindent The program for `{\manual\circf}' is similar, but `"fullcircle" scaled~$D$' is replaced by \begindisplay "unitsquare" shifted $-(.5,.5)$ rotated 45 scaled $(D/\rmsqrt2)$. \enddisplay \ansno14.6: There are inflection points, because there are no bounding triangles for the `$\ldots$' operations in the "superellipse" macro of Appendix~B, unless $.5\le s\le1$. \ansno14.7: $(0,0)\to(1,0)\;\&\;(1,0)\to(1,1)\;\&\;(1,1)\to(0,1) \;\&\;(0,1)\to(0,0)\;\&\;\cycle$. Incidentally, if each `\&' in this path is changed to `$\to$', we get a path that goes through the same points; but it is a path of length~8 that comes to a complete stop at each corner. In other words, the path remains motionless between times $1\le t\le2$, $3\le t\le4$, etc. This length-8 path therefore behaves somewhat strangely with respect to the `^{directiontime}' operation. It's better to use `\&' than to repeat points of a path. \ansno14.8: Let $\delta_1=z_1-z_0$, $\delta_2=z_2-z_1$, $\delta_3=z_0-z_2$; $l_1=\vert\delta_1\vert$, $l_2=\vert\delta_2\vert$, $l_3=\vert\delta_3\vert$; $\psi_1=\arg(\delta_2/\delta_1)$, $\psi_2=\arg(\delta_3/\delta_2)$, $\psi_3=\arg(\delta_1/\delta_3)$. The equations to be solved are $(\ast)$ and $({\ast}{\ast})$ for $1\le k\le3$, where $\alpha_3=\alpha_0$ and $\beta_4=\beta_1$. These six equations determine $\theta_1,\theta_2,\theta_3$ and $\phi_1,\phi_2,\phi_3$. \ansno14.9: The path is of length~9, and it is equivalent to `$(0,1)\dashto(1,1)\dashto(1,2)\dashto(0,2)\dashto(0,1)\{"down"\} \to\{"right"\}(1,0)\dashto(2,0)\dashto(2,1)\dashto(1,1)\dashto(1,0)$'. Although "unitsquare" is a cycle, the cycle is broken when it is used inside a larger path; the resulting non-cyclic square path goes "down" when it ends and "right" when it begins. \ansno14.10: Yes; for example, `$z_0\to z_1\to z_2\dashto z_3$' would be equivalent to `$z_0\to z_1\to\{\curl2\}z_2\{\curl2\}\to\{\curl2\}z_3$'. But a path like $z_0\dashto z_1\dashto z_2\dashto z_3$ would not be affected, because all directions would turn out to be the same as before. (The path `$z_0\{\curl a\}\to\{\curl b\}z_1$' is a straight line regardless of the values of $a$ and~$b$, because equations $({\ast}{\ast}{\ast})$ and $({\ast}{\ast}{\ast}')$ always have the solution $\theta_0=\phi_1=0$ when $n=1$.) \ansno14.11: It treats this as `$((0,0)\to(3,3)\to\cycle)\{\curl1\}$'; i.e., the part up to and including `cycle' is treated as a subpath (cf.~`|p2|' in Chapter~8). The cycle is broken, after which we have `$(0,0)\to\controls\,(2,-2)\and(5,1)\to(3,3)\to\controls\,(1,5)\and (-2,2)\to(0,0)\{\curl1\}$'. Finally the `$\{\curl1\}$' is dropped, because all control points are known. \ (The syntax by itself isn't really enough to answer this question, as you probably realize. You also need to be told that the computation of directions and control points is performed whenever \MF\ uses the second or third alternative in the definition of \<path expression>.) \ansno14.12: True. The length of a path is the number of `$z_k\to\controls u_k\and v_{k+1}\to z_{k+1}$' segments that it contains, after all control points have been chosen. \ansno14.13: True if $0\le t\le1$, except perhaps for rounding errors; otherwise false. The path $z_0\dashto z_1$ expands into `$z_0\to \controls1/3[z_0,z_1]\and2/3[z_0,z_1]\to z_1$', and the ^{Bernshte\u\i n} polynomial simplifies because $t[w,w+\delta,w+2\delta,w+3\delta]=w+3t\delta$. Incidentally, `point~$t$ of $(z_0\ddashto z_1)$' is usually quite different from $t[z_0,z_1]$. \ansno14.14: If $p$ is a cycle, or if $p$ is a path of length $\ge4$, the stated subpath has length~2. Otherwise the length is $\max(0,{\rm length}\,p-2)$. \ansno14.15: @vardef@ "posttension" @expr@ $t$ of $p$ $=$\parbreak \quad@save@ $q$; @path@ $q$;\parbreak \quad$q={\rm point}\,t\,{\rm of}\,p\,\{{\rm direction}\,t\,{\rm of}\,p\} \to\{{\rm direction}\,t\!+\!1\,{\rm of}\,p\}\, {\rm point}\,t\!+\!1\,{\rm of}\,p$;\parbreak \quad length(postcontrol 0 of $q$ $-$ point 0 of $q$)\parbreak \qquad/length(postcontrol $t$ of $p$ $-$ point t of $p$) @enddef@;\parbreak @vardef@ "pretension" @expr@ $t$ of $p$ $=$\parbreak \quad@save@ $q$; @path@ $q$;\parbreak \quad$q={\rm point}\,t\!-\!1\,{\rm of}\,p\,\{{\rm direction}\, t\!-\!1\,{\rm of}\,p\}\to\{{\rm direction}\,t\,{\rm of}\,p\}\, {\rm point}\,t\,{\rm of}\,p$;\parbreak \quad length(precontrol 1 of $q$ $-$ point 1 of $q$)\parbreak \qquad/length(precontrol $t$ of $p$ $-$ point t of $p$) @enddef@; \par\nobreak\smallskip\noindent The stated posttension turns out to be 4.54019. \ansno14.16: The `\&' had to be changed to `$\to$', because point~$t$ of~$p$ might not be exactly equal to point~$u$ of~$q$. \ansno14.17: Since $p$ intersects itself infinitely often at times $(t,t)$, the task may seem impossible; but \MF's shuffled-binary search procedure provides a way. Namely, $p$~intersectiontimes reverse~$p$~$=$ $(0.17227,0.28339)$, from which we can deduce that $t=0.17227$ and $1-u=0.28339$. \ansno15.1: |(x,-y)|. \ansno15.2: $(x,y)$ rotated 180, or $(x,y)$ scaled $-1$. \ansno15.3: True if and only if ${\rm xpart}\,t={\rm ypart}\,t=0$. If the stated equation holds for at least one pair $(x,y)$, it holds for all $(x,y)$. According to the syntax of Chapter~8, \MF\ interprets `$-(x,y)$ transformed~$t$' as $\bigl(-(x,y)\bigr)$ transformed~$t$. \ (Incidentally, mathematicians call \MF's transformers ``^{affine transformations},'' and the special case in which the xpart and ypart are zero is called ``^{homogeneous}.'') \ansno15.4: $z_1+z_2$. \ansno15.5: @beginchar@$(126,25u\0,"hheight"\0+"border"\0,0)$; |"Dangerous left bend"|;\parbreak $"currentpicture":="dbend"$ reflectedabout $\bigl((.5w,0),(.5w,h)\bigr)$; \ @endchar@;\medskip\noindent The same idea can be used to create right ^{parentheses} as perfect mirror images of left parentheses, etc., if the parentheses aren't slanted. \ansno15.6: Change line 9 to \begindisplay @draw@ $(z_1\ldots p)$ rotatedaround$\bigl((.5w,.5h),-45\bigr)$\cr \quad @withpen@ @pencircle@ scaled 3/4"pt" yscaled 1/3 rotated $-15$;\cr \enddisplay \ansno15.7: Replace line 10 by \begindisplay @pickup@ @pencircle@ scaled 3/4"pt" yscaled 1/3 rotated $-60$;\cr @draw@ ($z_1\ldots p$) transformed $t$;\cr \enddisplay \ansno16.1: If there are two points $z_k$ and $z_{k+1}$ with maximum $y$-coordinate, the value of `penoffset $(-"infinity","epsilon")$ of~$p$' will be~$z_k$ and `penoffset $(-"infinity",-"epsilon")$ of~$p$' will be~$z_{k+1}$; `penoffset~"left" of~$p$' will be one or the other. If there's only one top point, all three of these formulas will produce it. \ (Actually \MF\ also allows pens to be made with three or more vertices in a straight line. If there are more than two top vertices, you can use penoffset to discover the first and the last, as above; furthermore, if you really want to find them all, ^@makepath@ will produce a path from which they can be deduced in a straightforward manner.) \ansno16.2: `@pencircle@ scaled 1.016471' is the diamond but `@pencircle@ scaled 1.016472' is the square. \ (This assumes that ^"fillin"$\null=0$. If, for example, $"fillin"=.1$, the change doesn't occur until the diameter is 1.19325.) \ The next change is at diameter 1.5, which gives a diamond twice the size of the first. \ansno17.1: $(a+1)+(2a+2)=3a+3$ and $(2a)+(2a+1)=4a+1$, respectively. The final value of~$x$ in the first case is $2a+2$, hence $a=.5x-1$; |expr| will report the answer as |1.5x| (in terms of $x$'s new value), since it has not been told about `$a$'. In the second case |expr| will, similarly, say |2x-1|.\par This example shows that $\alpha+\beta$ is not necessarily equal to ^^{commutativity} $\beta+\alpha$, when $\alpha$ and~$\beta$ involve group expressions. \MF\ evaluates expressions strictly from left to right, performing the statements within groups as they appear. \ansno17.2: The save instruction gives `?' a fresh meaning, hence `?' is a numeric variable unconnected to any other variables. When the group ends and `?' is restored to its old meaning, the value of the group expression no longer has a name. \ (It's called a ``^{capsule}'' if you try to @show@ it.) \ Therefore the value of the group expression is a new, nameless variable, as desired. \ansno17.3: It's a nameless pair whose xpart and ypart are equal; thus it is essentially equivalent to `$"whatever"\ast(1,1)$'. \ansno17.4: `$v_3:=@begingroup@$ @save@ ?; @picture@ ?; ?\ @endgroup@' refreshes the picture variable~$v_3$ without changing other variables like~$v_2$. This construction works also for pairs, pens, strings, etc. \ansno18.1: Yes; the direction at |z.j| will be either "left" or "right". \ansno18.2: |beginlogochar("A",15);| \rightfig A18a ({240\apspix} x {216\apspix}) ^3pt \parbreak |x1=.5w;|\parbreak |x2=x4=leftstemloc;|\parbreak |x3=x5=w-x2;|\parbreak |top y1=h+o;|\parbreak |y2=y3=barheight;|\parbreak |bot y4=bot y5=-o;|\parbreak |draw z4--z2--z3--z5;|\parbreak |super_half(2,1,3);|\parbreak |labels(1,2,3,4,5);|\parbreak |endchar;|\par\smallskip\noindent Notice that all three calls of |super_half| in |logo.mf| are of the form `"super\_half"$(2,j,3)$'. But it would not be good style to eliminate parameters $i$ and~$k$, even though |super_half| is a ^{special-purpose} subroutine; that would make it too too special. \ansno18.3: If $"bracket"=0$ or $"serif\_darkness"=0$. \ (It's probably not a good idea to make $"serif\_darkness"=0$, because this would lead to an extreme case of the `$\ldots$' triangle, ^^{...} which might not be numerically stable in the presence of rounding errors.) \ansno18.4: That's a strange question. The "serif" routine includes a "penpos" that defines $z_{\$l}$, $z_\$$, and $z_{\$r}$ relative to each other, and it defines the other six points relative to them. Outside the routine the user ought to specify just one $x$-coordinate and one $y$-coordinate, in order to position all of the points. This can be done either before or after "serif" is called, but \MF\ has an easier job if it's done beforehand. \ansno18.5: Yes; see the previous exercise. \ (But in the program for |"A"| it's necessary to define $y_{4l}$ and $y_{5r}$, so that $"theta"_4$ and~$"theta"_5$ can be calculated.) \ansno18.6: \rightfig A18b (48mm x 43mm) ^10pt @beginchar@\kern1pt(|"H"|$,13u\0,"ht"\0,0)$;\parbreak $x_1=x_2=x_5=3u$;\parbreak $x_3=x_4=x_6=w-x_1$;\parbreak $y_{1c}=y_{3c}=h$; \ $y_{2c}=y_{4c}=0$;\parbreak $"serif"(1,"thick",-90,"jut","jut")$;\parbreak $"serif"(2,"thick",90,"jut","jut")$;\parbreak $"serif"(3,"thick",-90,"jut","jut")$;\parbreak $"serif"(4,"thick",90,"jut","jut")$;\parbreak @fill@ $"serif\_edge"_2$\parbreak \quad$\dashto{\rm reverse}\,"serif\_edge"_1\dashto\cycle$;\parbreak @fill@ $"serif\_edge"_4$\parbreak \quad$\dashto{\rm reverse}\,"serif\_edge"_3\dashto\cycle$;\parbreak $\penpos5("thin",90)$; \ $\penpos6("thin",90)$;\parbreak $y_5=y_6=.52h$; \ @penstroke@ $z_{5e}\dashto z_{6e}$;\parbreak @penlabels@$(1,2,3,4,5,6)$; \ @endchar@. \ansno18.7: @def@ "top\_serif"(@suffix@ \$)(@expr@ $"xx","theta", "left\_jut","right\_jut")=$\parbreak \quad $\penpos\$("xx",0)$; \ $z_{\$a}-z_{\$l}=z_{\$\mkern-1muf}-z_{\$r}= ("bracket"/{\rm abs\,sind\,}"theta")\ast{\rm dir}\,"theta"$;\parbreak \quad $y_{\$c}=y_{\$d}=y_\$$; \ $x_{\$c}=x_{\$l}-"left\_jut"$; \ $x_{\$d}=x_{\$r}+"right\_jut"$;\parbreak \quad $z_{\$b}=z_{\$l}+"whatever"\ast{\rm dir}\,"theta" =z_{\$c}+"whatever"\ast{\rm dir}\,{-"phi"}$;\parbreak \quad $z_{\$e}=z_{\$r}+"whatever"\ast{\rm dir}\,"theta" =z_{\$d}+"whatever"\ast{\rm dir}\,"phi"$;\parbreak \quad @labels@$(\$a,\$b,\$c,\$d,\$e,\$\mkern-1muf)$ @enddef@;\par \smallskip\indent @def@ "top\_serif\_edge" @suffix@ \$ $=$\parbreak \quad $\bigl(z_{\$a}\to\controls z_{\$b}\to z_{\$c}$\parbreak \qquad $\dashto("flex"(z_{\$c},.5[z_{\$c},z_{\$d}]-"dishing", z_{\$d}))$ shifted $(0,+"epsilon")$\parbreak \qquad $\dashto z_{\$d}\to\controls z_{\$e}\to z_{\$\mkern-1muf} \bigr)$ @enddef@; \ansno18.8: Assuming that $"py"=0$, the effective right stroke weight would be $"px"\cdot\sin(\theta_5-\phi)$ if it were drawn with one stroke of "broad\_pen", and $"xxx"\cdot\sin\theta_5$ is the additional weight corresponding to separate strokes "xxx" apart. The right-hand side of the equation is the same calculation in the case of vertical strokes ($\theta=90^\circ$), when the stroke weight of |"I"| is considered. \ (Since a similar calculation needs to be done for the letters K, V, W, X, Y, and Z, it would be a good idea to embed these details in another macro.) \ansno18.9: \rightfig A18c (48mm x 45mm) ^10pt @beginchar@\kern1pt(|"H"|$,13u\0,"ht"\0,0)$;\parbreak $x_1=x_2=x_5=3u$;\parbreak $x_3=x_4=x_6=w-x_1$;\parbreak $y_1=y_3=h$; \ $y_2=y_4=0$;\parbreak $"top\_serif"(1,"xx",-90,"jut","jut")$;\parbreak $"bot\_serif"(2,"xx",90,"jut","jut")$;\parbreak $"top\_serif"(3,"xx",-90,"jut","jut")$;\parbreak $"bot\_serif"(4,"xx",90,"jut","jut")$;\parbreak @filldraw@ $"bot\_serif\_edge"_2$\parbreak \quad$\dashto{\rm reverse}\,"top\_serif\_edge"_1\dashto\cycle$;\parbreak @fill@ $"bot\_serif\_edge"_4$\parbreak \quad$\dashto{\rm reverse}\,"top\_serif\_edge"_3\dashto\cycle$;\parbreak $y_5=y_6=.52h$; \ @draw@ $z_5\dashto z_6$;\parbreak @penlabels@$(1,2,3,4,5,6)$; \ @endchar@. \ansno18.10: The replacement text contains ten tokens, \begindisplay \ttok{def}\quad\<t>\quad\ttok{=}\quad\<e>\quad\ttok{enddef} \quad\ttok{;}\quad\ttok{def}\quad\ttok{t}\quad\ttok{=}\quad\<p> \enddisplay where \<t>, \<e>, and \<p> are placeholders for argument insertion. When this macro is expanded with $"tracingmacros">0$, \MF\ will type \begintt foo(TEXT0)<expr>of<primary>->def(TEXT0)=(EXPR1)enddef;def.t=(EXPR2) \endtt followed by the arguments |(TEXT0)|, |(EXPR1)|, and |(EXPR2)|. \ansno18.11: According to the rule just stated, the first comma is an abbreviation for `|}}|~|{{|'. Hence the first argument is a capsule containing the value of~$x$; the second is the text `|(,|'\thinspace; the third is the text `|(}})|'. \ansno18.12: This snares ^{future pen}s before they're converted to pens, because @pickup@ wants to yscale by "aspect\_ratio" before ellipses change to polygons. \ansno18.13: The construction `"hide"\thinspace(\<statement list>)' expands into `"gobble" @begingroup@ \<statement list>; @endgroup@', so the argument to "gobble" must be evaluated. The @begingroup@ causes \MF\ to start executing statements. When that has been done, the final statement turns out to be \<empty>, so the argument to "gobble" turns out to be a ^{vacuous} expression (cf.\ Chapter~25). Finally, "gobble"'s replacement text is empty, so the hidden text has indeed disappeared. \ (The "hide" macro in Appendix~B is actually a bit more efficient, but a bit trickier.) \ansno19.1: Then \MF's ``stomach'' would see `;' if "mag" is known, but there would be no change if "mag" is unknown. An extra semicolon is harmless, since \MF\ statements can be \<empty>. But it's wise to get in the habit of putting `;' before @fi@, because it saves a wee bit of time and because `;' definitely belongs before ^@endfor@. \ansno19.2: No; that would be shocking. \ansno19.3: Yes, if and only if $n-{1\over2}$ is an even integer. \ (Because ambiguous values are rounded up.) \ansno19.4: No. \ansno19.5: @def@ even $=$ not odd @enddef@. \ansno19.6: The first is~5, because the pair is not considered to be a path. The second and third are~0, because the pair is forced to become a path. \ansno19.7: (a) The loop text is never executed. \ (b)~It's executed only once, for $x=1$. \ (c)~It's executed infinitely often, for $x=1,1,1,\ldots\,$. \ (d)~Since ten times \MF's internal representation of .1 is slightly larger than 1, the answer is not what you probably expect! The loop text is executed for $x=0$,~0.1, 0.20001, 0.30002, 0.40002, 0.50003, 0.60004, 0.70004, 0.80005, and 0.90005 only. \ (If you want the values $(0,.1,.2,\ldots,1)$, say `\thinspace@for@ $"xx"=0$ @upto@~10: $x:="xx"/10$; \<text> @endfor@' instead.) \ansno19.8: $m=1$, $n=0$. \ansno19.9: @def@ @exitunless@ @expr@ $b$ $=$ @exitif@ not $b$ @enddef@. \ (The simpler alternative `@def@ @exitunless@ $=$ @exitif@ not @enddef@\kern1pt' wouldn't work, since `not' applies only to the following \<primary>.) \ansno19.10: |numeric p[]; boolean n_is_prime; p[1]=2; k:=1;|\parbreak |for n=3 step 2 until infinity:|\parbreak | n_is_prime:=true;|\parbreak | for j=2 upto k: if n mod p[j]=0: n_is_prime:=false; fi|\parbreak | exitif n/p[j]<p[j]; endfor|\parbreak | if n_is_prime: p[incr k]:=n; exitif k=30; fi|\parbreak | endfor fi|\parbreak ^^@show@^^@str@ |show for k=1 upto 30: str p[k]&"="&decimal p[k], endfor "done" end.| \ansno19.11: `|0; exitif true;|'. \ansno20.1: False; consider `|a1(2)|'. \ansno20.2: A value very close to $z_2$. \ansno20.3: |vardef lo_cube(expr x)=x*x*x<10 enddef;|\parbreak |show solve lo_cube(0,10), 10**1/3; end.|\par\nobreak\medskip\noindent ^^{**} With the default ^"tolerance" of 0.1, this will show the respective values |2.14844| and |2.1544|. A more general routine could also be written, with `10' as a parameter: \begintt vardef lo_cube[](expr x)=x*x*x<@ enddef; show solve lo_cube10(0,10); \endtt if we ask for minimum tolerance ($"tolerance":="epsilon"$), the result is |2.15445|; the true value is $\approx 2.15443469$. \ansno20.4: |begingroup(p5dx,p5dy)endgroup|. \ansno20.5: Say `|first#@|' after defining `|vardef| |first.a[]@#=@| |enddef|'. \ (There are other solutions, e.g., using substrings of ^@str@~|#@|, but this one is perhaps the most instructive.) \ansno20.6: The machine answers thus: \begintt incr=macro:<suffix>-> begingroup(SUFFIX2):=(SUFFIX2)+1;(SUFFIX2)endgroup z@#=macro:->begingroup(x(SUFFIX2),y(SUFFIX2))endgroup \endtt Parameters to a macro are numbered sequentially, starting with zero, and classified as either ^|(EXPR|$_n$|)|, ^|(SUFFIX|$_n$|)|, or ^|(TEXT|$_n$|)|. In a vardef, |(SUFFIX0)| and |(SUFFIX1)| are always reserved for the implicit parameters |#@| and~|@|; |(SUFFIX2)| will be |@#|, if it is used in the parameter heading, otherwise it will be the ^^{at sharp} ^^{at} ^^{sharp at} first explicit parameter, if it happens to be a suffix parameter. \ansno20.7: |secondarydef t transum tt =|\parbreak | begingroup save T; transform T;|\parbreak | for z=origin,up,right:|^^"origin"\parbreak | z transformed t + z transformed tt = z transformed T; endfor|\parbreak | T endgroup enddef.| \ansno21.1: False; about twice as often (2/3 versus 1/3). \ansno21.2: |1+floor uniformdeviate n|. \ansno21.3: A random point on the straight line segment from $z_1$ to $z_2$. \ (The point $z_1$ itself will occur with probability about 1/65536; but point $z_2$ will never occur.) \ansno21.4: A random ``^{skyline}'' texture, $100\pt$ wide $\times$ $10\pt$ tall: {\rand\char127} The density decreases uniformly as you go up in altitude. \ansno21.5: A more-or-less bell-shaped ^{histogram}: {\rand\char126} \ansno22.1: (a) Iff $n$ is an integer between 0 and 127. (b) Iff $s$ is a string of length~1. \ansno22.2: Whoever says that there's no such primitive operation has forgotten about @scantokens@. \ansno22.3: |vardef octal primary n =|\parbreak | save m,s; m:=abs round n; string s; s=decimal(m mod 8);|\parbreak | forever: m:=m div 8; exitif m=0;|\parbreak | s:=decimal(m mod 8) & s; endfor|\parbreak | s enddef;|\par\nobreak\medskip\noindent `|str[m mod 8]|' could also be used instead of `|decimal(m mod 8)|'. \ansno23.1: Point $(x,y)$ is the upper left corner, ${(x+c_1-c_0,y)}$ is the upper right corner, ${(x,y-r_1+r_0)}$ is the lower left corner, and ${(x+c_1-c_0,y-r_1+r_0)}$ is the lower right corner. \ (Pixels outside this rectangle will not be displayed.) \ansno23.2: Redefine @openit@ so that it puts the top left at $(-50,280)$. \ansno23.3: (This routine is due to John ^{Hobby}.) \begintt newinternal n_windows; % the number of windows allocated so far newinternal screen_bot; % the first untouched screen row pair screen_corner; % the upper left corner of next window def wipescreen = % do this to initialize or reinitialize for i:=1 upto n_windows: display blankpicture on i; endfor n_windows := screen_bot := 0; screen_corner := origin enddef; wipescreen; vardef new_window@#(expr u,v) = save r,c,up_lft; pair up_lft; if n_windows=15: errmessage "No more windows left" else: window@# := incr n_windows; up_lft = (min(xpart u,xpart v), max(ypart u, ypart v)); (r,c) = (u+v-2up_lft) rotated 90; if ypart screen_corner + c > screen_cols: screen_corner:=(screen_bot,0); fi openwindow window@# from screen_corner to screen_corner+(r,c) at up_lft; screen_bot := max(screen_bot,xpart screen_corner + r); screen_corner := screen_corner + (0,c) fi; enddef; \endtt \ansno24.1: The entire path now has negative $y$-coordinates except at point~$(0,0)$, so the outline of the filled region is $(0,-1)\dashto(10,-1)\dashto(10,0)\dashto(0,0)\dashto(0,1) \dashto\cycle$. \ $\bigl($Notice that the digitized outline actually goes up to $(0,1)$ before coming straight down again. This fills no pixels, but \MF\ correctly puts ``cancelling'' edges from $(0,0)$ to $(0,1)$ and back to $(0,0)$ into its edge structure, because the point $(0,.5)$ is on the boundary and rounds to $(0,1).\bigr)$ \ansno24.2: The horizontal tangents are already taken care of by the equations $"top"\,y_1=h+o$ and $"bot"\,y4=-o$, so nothing needs to be done there. We should, however, say \begindisplay $x_2=w-x_3="good.x"(1.5u+s)$ \enddisplay so that vertical tangents will occur in good places. Since $w$~is an integer, and since the "logo\_pen" has left-right symmetry, $w-x_3$ will be good if and only if $x_3$ is. \ansno24.3: Let $b$ be the pen breadth. Then $.5w$ is a good $x$ value if and only if $"lft"\,.5w$ is an integer; but $"lft"\,.5w=.5w-.5b$, and this is an integer if and only if $w-b$ is even. \ansno24.4: There are no ambiguous points on the outlines of this stroke, except perhaps on the top and bottom edges; the latter can occur only if $\round"py"$ is odd. Hence there is always left-right symmetry, but top-bottom symmetry might fail because of a missing row at the bottom (e.g., when $"px"="py"=3$). In a case like the `\kern1pt{\manual j}\kern1pt' we do have both symmetries, because $y_1$ and $x_4$ are in good positions. \ansno24.5: No matter where you place the octagon so that it isn't touching any ambiguous points, exactly seven ambiguous points are inside it; hence every one-point ^@draw@ fills exactly seven pixels. \ (In fact, you always get one of the patterns $\vcenter{\vbox{\offinterlineskip\manual \hbox{\kern\Blankpix RR}\hbox{RRR}\hbox{\kern\Blankpix RR}\kern1pt}}$, $\vcenter{\vbox{\offinterlineskip\manual \hbox{\kern\Blankpix R}\hbox{RRR}\hbox{RRR}\kern1pt}}$, $\vcenter{\vbox{\offinterlineskip\manual \hbox{RR}\hbox{RRR}\hbox{RR}\kern1pt}}$, or $\vcenter{\vbox{\offinterlineskip\manual \hbox{RRR}\hbox{RRR}\hbox{\kern\Blankpix R}\kern1pt}}$.) \ansno24.6: $f=.5(x_4-x_3)$; the desired equation is `$x_1-x_2=\round\bigl(x_1-x_2+.5(x_4-x_3)\bigr)$'. \ansno24.7: Let $x_3=n+{1\over2}+\theta$, where $n$ is an integer and $0\le\theta<1$. By drawing lines of slope~$30^\circ$ from the pixel centers, we find that there are three cases for the rightmost four columns: \begindisplay Case A, $\vcenter{\vbox{\offinterlineskip\manual \hbox{RR}\hbox{RRRR}\hbox{RR}\kern1pt}}$;\qquad Case B, $\vcenter{\vbox{\offinterlineskip\manual \hbox{R}\hbox{RR}\hbox{RRRR}\hbox{RR}\hbox{R}\kern1pt}}$;\qquad Case C, $\vcenter{\vbox{\offinterlineskip\manual \hbox{R}\hbox{RRR}\hbox{RRRR}\hbox{RRR}\hbox{R}\kern1pt}}$. \enddisplay Case A occurs for $0\le\theta<2\sqrt3-3$; Case B occurs for $2\sqrt3-3\le\theta<\sqrt3-1$; Case~C occurs for $\sqrt3-1\le\theta<1$. The tip in Case~A looks a bit too sharp, and Case~C looks too blunt, so Case~B seems best. This case occurs when $x_3$ is near an integer, so it's OK to let $x_3$ be an integer. \ansno24.8: Let $y_1=n+\theta$. If $\theta$ lies between ${1\over2}\sqrt3-{1\over2}$ and ${1\over6}\sqrt3+{1\over2}$, the top row after digitization will contain two black pixels. If $\theta$ lies between ${1\over6}\sqrt3+{1\over2}$ and ${5\over6}\sqrt3-{1\over2}$, we get the desired shape. Otherwise we get `\thinspace$\vcenter{\vbox{\offinterlineskip\manual \hbox{R}\hbox{RRR}\hbox{RRRR}\kern1pt}}$'. \ansno24.9: (We choose $\theta={1\over2}\sqrt3$ in the previous exercise, since ^^{floor} this is the midpoint of the desirable interval.) The equations are changed to \begindisplay $x_1=x_2=w-x_3=\round s$;\cr $y_3=.5+{\rm floor}\,.5h$;\cr $z_1-z_2=(z_3-z_2)$ rotated 60;\cr $y_1:=.5\rmsqrt3+\round(y_1-.5\rmsqrt3)$;\cr $y_2:=h-y_1$;\cr \enddisplay and then we @fill@ $z_1\dashto z_2\dashto z_3\dashto\cycle$ as before. \ansno24.10: @vardef@ "vround" @primary@ $v$ $=$\parbreak \qquad floor$(v\ast"aspect\_ratio"+.5)/"aspect\_ratio"$ @enddef@;\parbreak @vardef@ "good.y" @primary@ $y$ $=$\parbreak \qquad "vround"$(y+"pen\_top")-"pen\_top"$ @enddef@. \ansno24.11: $\bigl(m+1/2,(n+1/2)/"aspect\_ratio"\bigr)$. These are the points that "currenttransform" maps into pixel centers. \ansno25.1: By looking at the syntax rules, we find, for example, \begindisplay \<boolean expression>&|true|\cr \<numeric expression>&|0|\cr \<pair expression>&|(0,0)|\cr \<path expression>&|makepath pencircle|\cr \<pen expression>&|nullpen|\cr \<picture expression>&|nullpicture|\cr \<string expression>&|""|\cr \<transform expression>&Impossible!\cr \<vacuous expression>&|begingroup endgroup|\cr \enddisplay Every \<transform expression> includes either a variable or a capsule. Incidentally, there are some amusing alternative 5-token solutions for \<pair expression>: \begintt postcontrol 0 of makepath nullpen makepath pencircle intersectiontimes makepath nullpen \endtt \ansno26.1: The responses are \begintt > a=left delimiter that matches :: > b=(outer) a > c=a \endtt because: $a$ has been redefined from internal quantity to delimiter; $b$~is still an internal quantity (named~$a$), and it has been stamped @outer@; $c$~denotes the same internal quantity, but it hasn't got outerness. \ansno27.1: We want to delete \begindisplay \ttok{0}\quad\ttok{[}\quad\ttok{1}\quad\ttok{+}\quad\ttok{sqrt}\quad \ttok{43}\quad\ttok{]} \enddisplay from the sequence of tokens that \MF\ is about to read next, in order to get rid of the right bracket, which we can see is going to be just as erroneous as the left bracket was. However, there is another way to proceed (and indeed, this alternative would be preferable to counting tokens, if the bracketed expression were longer): We could simply ^^{delimiter} ^^|Missing token has been inserted| delete 2~tokens, then `|I(|'. This would produce another error stop, \begintt ! Missing `)' has been inserted. <to be read again> ] <*> show round[1 + sqrt43] ; ? h I found no right delimiter to match a left one. So I've put one in, behind the scenes; this may fix the problem. ? \endtt after which it's easy to delete the `|]|' and continue successfully. \ansno27.2: \MF\ looked ahead, to see if the expression being evaluated was going to be something like `|round 0[1+sqrt43,x]|'. But when it found no comma, it put back several tokens so that they could be read again. \ (The subexpression |1+sqrt43| had already been evaluated, so a ``^{capsule}'' for its value, 7.55743, was inserted among the tokens to be reread.) \ The expression ended with `0', and `round~0' was shown. Then \MF\ found extra tokens following the @show@ command; a semicolon should have come next. To continue, the user should just plunge ahead recklessly once again, letting \MF\ delete those unwanted tokens. \ansno27.3: The little program \begintt path p,q; p=flex((-32,481),(-42,455),(-62,430)); q=flex((-62,430),(-20,452),(42,448)); show p intersectiontimes q, p intersectionpoint q, angle -direction 2 of p, angle direction 0 of q; end \endtt gives the following results: \begintt >> (1.88403,0.07692) >> (-59.32149,432.59523) >> 43.14589 >> 45.47263 \endtt (Actually, the paths would also cross if |452| were |451|, but it's such a close call that \MF\ doesn't call the path strange; \MF\ prefers to turn ^{counterclockwise} when the amount of turn is close enough to $180^\circ$, even if it's slightly more.) \ansno27.4: If this exercise isn't just a joke, the title of this appendix is a lie. \ (When you've solved this exercise you might also try to find all the lies and/or jokes that are the same in both this book and {\sl The \TeX book}.)