ńņš. 16 |

The oval shape that encloses this tree is a superellipse , which is another special

kind of path provided by plain . To get a general shape of this kind,

you can write

superellipse (right point , top point , left point , bottom point , superness )

where ā˜superness ā™ controls the amount by which the curve diļ¬ers from a true

ellipse. For example, here are four superellipses, drawn with varying amounts of

superness, using a pencircle xscaled 0.7pt yscaled 0.2pt rotated 30:

(Figure 14c will be inserted here; too bad you canā™t see it now.)

The superness should be between 0.5 (when you get a diamond) and 1.0 (when

you get a square); values in the vicinity of 0.75 are usually preferred. The zero

symbol ā˜0ā™ in this bookā™s typewriter font was drawn as a superellipse of superness

2ā’.5 ā .707, which corresponds to a normal ellipse; the uppercase letter ā˜Oā™ was

drawn with superness 2ā’.25 ā .841, to help distinguish it from the zero. The

ambiguous symbol ā˜Ā¼ā™ (which is not in the font, but can of course

draw it) lies between these two extremes; its superness is 0.77.

A mathematical superellipse satisļ¬es the equation |x/a|Ī² + |y/b|Ī² = 1, for

some exponent Ī². It has extreme points (Ā±a, 0) and (0, Ā±b), as well as the

ācornerā points (Ā±Ļa, Ā±Ļb), where Ļ = 2ā’1/Ī² is the superness. The tangent to the

curve at (Ļa, Ļb) runs in the direction (ā’a, b), hence it is parallel to a line from (a, 0)

to (0, b). Gabriel LamĀ“ invented the superellipse in 1818, and Piet Hein popularized the

e

special case Ī² = 2.5 [see Martin Gardner, Mathematical Carnival (New York: Knopf,

1975), 240ā“254]; this special case corresponds to a superness of 2ā’.4 ā .7578582832552.

ā™s superellipse routine does not produce a perfect superellipse, nor

Plain

does fullcircle yield a true circle, but the results are close enough for practical purposes.

EXERCISE 14.6

Try superellipse with superness values less than 0.5 or greater than 1.0; explain

why you get weird shapes in such cases.

Chapter 14: Paths 127

Letā™s look now at the symbols that are used between key points, when ..

...

we specify a path. There are ļ¬ve such tokens in plain : ā“

ā”

.. free curve; ampersand

ļ¬‚ex

... bounded curve; autorounding

-- straight line;

--- ātenseā line;

& splice.

In general, when you write ā˜z0 . . z1 . . etc. . . znā’1 . . zn ā™, will

compute the path of length n that represents its idea of the āmost pleasing

curveā through the given points z0 through zn . The symbol ā˜. . .ā™ is essentially

the same as ā˜. .ā™ , except that it conļ¬nes the path to a bounding triangle whenever

possible, as explained in Chapter 3. A straight line segment ā˜zkā’1 - - zk ā™ usually

causes the path to change course abruptly at zkā’1 and zk . By contrast, a segment

speciļ¬ed by ā˜zkā’1 - - - zk ā™ will be a straight line that blends smoothly with the

neighboring curves; i.e., the path will enter zkā’1 and leave zk in the direction of

zk ā’ zkā’1 . (The trunk of El Palo Alto makes use of this option, and we have

also used it to draw the signboard of the dangerous bend symbol at the end of

Chapter 12.) Finally, the ā˜&ā™ operation joins two independent paths together

at a common point, just as ā˜&ā™ concatenates two strings together.

Here, for example, is a somewhat silly path that illustrates all ļ¬ve basic

types of joinery:

(Figure 14d will be inserted here; too bad you canā™t see it now.)

z0 = (0, 100); z1 = (50, 0); z2 = (180, 0);

for n = 3 upto 9: z[n] = z[n ā’ 3] + (200, 0); endfor

draw z0 . . z1 - - - z2 . . . {up }z3

& z3 . . z4 - - z5 . . . {up }z6

& z6 . . . z7 - - - z8 . . {up }z9 .

The ā˜. . .ā™ operation is usually used only when one or both of the adjacent

directions have been speciļ¬ed (like ā˜{up }ā™ in this example). Plain -

ā™s ļ¬‚ex construction actually uses ā˜. . .ā™ , not ā˜. .ā™ as stated earlier, because this

avoids inļ¬‚ection points in certain situations.

A path like ā˜z0 - - - z1 - - - z2 ā™ is almost indistinguishable from the broken

line ā˜z0 - - z1 - - z2 ā™, except that if you enlarge the former path you will see

that its lines arenā™t perfectly straight; they bend just a little, so that the curve is

āsmoothā at z1 although thereā™s a rather sharp turn there. (This means that the

autorounding operations discussed in Chapter 24 will apply.) For example, the path

128 Chapter 14: Paths

(0, 3) - - - (0, 0) - - - (3, 0) is equivalent to unitsquare

tensepath

curl

(0, 3) . . controls (ā’0.0002, 2.9998) and (ā’0.0002, 0.0002)

. . (0, 0) . . controls (0.0002, ā’0.0002) and (2.9998, ā’0.0002) . . (3, 0)

while (0, 3) - - (0, 0) - - (3, 0) consists of two perfectly straight segments:

(0, 3) . . controls (0, 2) and (0, 1)

. . (0, 0) . . controls (1, 0) and (2, 0) . . (3, 0).

EXERCISE 14.7

ā™s unitsquare path is deļ¬ned to be ā˜(0, 0) - - (1, 0) - - (1, 1) - -

Plain

(0, 1) - - cycleā™. Explain how the same path could have been deļ¬ned using only ā˜. .ā™

and ā˜&ā™, not ā˜- -ā™ or explicit directions.

Sometimes itā™s desirable to take a path and change all its connecting links

to ā˜- - -ā™, regardless of what they were originally; the key points are left un-

has a tensepath operation that does this. For example,

changed. Plain

tensepath unitsquare = (0, 0) - - - (1, 0) - - - (1, 1) - - - (0, 1) - - - cycle.

When is deciding what curves should be drawn in place of

ā˜. .ā™ or ā˜. . .ā™, it has to give special consideration to the beginning and ending points,

so that the path will start and ļ¬nish as gracefully as possible. The solution that

usually works out best is to make the ļ¬rst and last path segments very nearly

the same as arcs of circles; an unadorned path of length 2 like ā˜z0 . . z1 . . z2 ā™

will therefore turn out to be a good approximation to the unique circular arc

that passes through (z0 , z1 , z2 ), except in extreme cases. You can change this

default behavior at the endpoints either by specifying an explicit direction or by

specifying an amount of ācurl.ā If you call for curliness less than 1, the path will

decrease its curvature in the vicinity of the endpoint (i.e., it will begin to turn

less sharply); if you specify curliness greater than 1, the curvature will increase.

(See the deļ¬nition of El Palo Altoā™s trunk , earlier in this chapter.)

Here, for example, are some pairs of parentheses that were drawn using

various amounts of curl. In each case the shape was drawn by a statement of the

form ā˜penstroke z0e {curl c} . . z1e . . {curl c}z2e ā™; diļ¬erent values of c produce

diļ¬erent-looking parentheses:

Ā½Ā¾ Āæ

curl value 0 1 2 4 inļ¬nity

yields

(The parentheses of Computer Modern typefaces are deļ¬ned by the somewhat

more general scheme described in Chapter 12; explicit directions are speciļ¬ed at

the endpoints, instead of curls, because this produces better results in unusual

cases when the characters are extremely tall or extremely wide.)

The amount of curl should not be negative. When the curl is very large,

doesnā™t actually make an extremely sharp turn at the endpoint;

instead, it changes the rest of the path so that there is comparatively little curvature

at the neighboring point.

Chapter 14: Paths 129

Chapter 3 points out that we can change ā™s default curves by tension

path primary

specifying nonstandard ātensionā between points, or even by specifying ex-

(

plicit control points to be used in the four-point method. Let us now study the full )

syntax of path expressions, so that we can come to a complete understanding of the reverse

subpath

paths that is able to make. Here are the general rules: of

path secondary

path primary ā’ā’ pair primary | path variable path tertiary

| ( path expression ) path expression

| reverse path primary cycle

path subexpression

| subpath pair expression of path primary path join

path secondary ā’ā’ pair secondary | path primary direction speciļ¬er

| path secondary transformer ā“

curl

path tertiary ā’ā’ pair tertiary | path secondary Ė

path expression ā’ā’ pair expression | path tertiary ā“

Ė

| path subexpression direction speciļ¬er ā“

| path subexpression path join cycle ,

path subexpression ā’ā’ path expression Ė

basic path join

| path subexpression path join path tertiary &

path join ā’ā’ direction speciļ¬er basic path join direction speciļ¬er ..

direction speciļ¬er ā’ā’ empty ..

..

| { curl numeric expression } ..

| { pair expression } ..

tension

| { numeric expression , numeric expression } tension

basic path join ā’ā’ & | .. | .. tension .. | .. controls .. tension

tension ā’ā’ tension tension amount and

tension amount

| tension tension amount and tension amount atleast

tension amount ā’ā’ numeric primary controls

| atleast numeric primary controls

controls

controls ā’ā’ controls pair primary and

| controls pair primary and pair primary up

The operations ā˜. . .ā™ and ā˜- -ā™ and ā˜- - -ā™ are conspicuously absent from this syntax; that

is because Appendix B deļ¬nes them as macros:

... is an abbreviation for ā˜. . tension atleast 1 . .ā™ ;

is an abbreviation for ā˜{curl 1} . . {curl 1}ā™ ;

--

is an abbreviation for ā˜. . tension inļ¬nity . .ā™ .

---

These syntax rules specify a wide variety of possibilities, even though they

donā™t mention ā˜- -ā™ and such things explicitly, so we shall now spend a little

while looking carefully at their implications. A path expression essentially has the form

Ā·Ā·Ā·

p0 j1 p1 j2 jn pn

where each pk is a tertiary expression of type pair or path, and where each jk is a āpath

join.ā A path join begins and ends with a ādirection speciļ¬er,ā and has a ābasic path

joinā in the middle. A direction speciļ¬er can be empty, or it can be ā˜{curl c}ā™ for some

c ā„ 0, or it can be a direction vector enclosed in braces. For example, ā˜{up }ā™ speciļ¬es

deļ¬nes up to be the pair (0, 1). This

an upward direction, because plain

same direction could be speciļ¬ed by ā˜{(0, 1)}ā™ or ā˜{(0, 10)}ā™, or without parentheses as

ā˜{0, 1}ā™. If a speciļ¬ed direction vector turns out to be (0, 0), behaves as

130 Chapter 14: Paths

if no direction had been speciļ¬ed; i.e., ā˜{0, 0}ā™ is equivalent to ā˜ empty ā™. An empty tension

Hobby

direction speciļ¬er is implicitly ļ¬lled in by rules that we shall discuss later.

A basic path join has three essential forms: (1) ā˜&ā™ simply concatenates

two paths, which must share a common endpoint. (2) ā˜. . tension Ī± and Ī² . .ā™

means that a curve should be deļ¬ned, having respective ātensionsā Ī± and Ī². Both Ī±

and Ī² must be equal to 3/4 or more; we shall discuss tension later in this chapter.

(3) ā˜. . controls u and v . .ā™ deļ¬nes a curve with intermediate control points u and v.

Special abbreviations are also allowed, so that the long forms of basic path

joins can usually be avoided: ā˜. .ā™ by itself stands for ā˜. . tension 1 and 1 . .ā™ ,

while ā˜. . tension Ī± . .ā™ stands for ā˜. . tension Ī± and Ī± . .ā™ , and ā˜. . controls u . .ā™ stands for

ā˜. . controls u and u . .ā™ .

Our examples so far have always constructed paths from points; but the syn-

tax shows that itā™s also possible to write, e.g., ā˜p0 . . p1 . . p2 ā™ when the pā™s

themselves are paths. What does this mean? Well, every such path will already

have been changed into a sequence of curves with explicit control points; -

expands such paths into the corresponding sequence of points and basic path

joins of type (3). For example, ā˜((0, 0) . . (3, 0)) . . (3, 3)ā™ is essentially the same as

ā˜(0, 0) . . controls (1, 0) and (2, 0) . . (3, 0) . . (3, 3)ā™, because ā˜(0, 0) . . (3, 0)ā™ is the path

ā˜(0, 0) . . controls (1, 0) and (2, 0) . . (3, 0)ā™. If a cycle is expanded into a subpath in this

way, its cyclic nature will be lost; its last point will simply be a copy of its ļ¬rst point.

Now letā™s consider the rules by which empty direction speciļ¬ers can inherit

speciļ¬cations from their environment. An empty direction speciļ¬er at the

beginning or end of a path, or just next to the ā˜&ā™ operator, is eļ¬ectively replaced by

ā˜{curl 1}ā™. This rule should be interpreted properly with respect to cyclic paths, which

have no beginning or end; for example, ā˜z0 . . z1 & z1 . . z2 . . cycleā™ is equivalent to

ā˜z0 . . z1 {curl 1}&{curl 1}z1 . . z2 . . cycleā™.

If thereā™s a nonempty direction speciļ¬er after a point but not before it, the

nonempty one is copied into both places. Thus, for example, ā˜. . z{w}ā™ is

treated as if it were ā˜. . {w}z{w}ā™. If thereā™s a nonempty direction speciļ¬er before a

point but not after it, the nonempty one is, similarly, copied into both places, except

if it follows a basic path join that gives explicit control points. The direction speciļ¬er

that immediately follows ā˜. . controls u and v . .ā™ is always ignored.

An empty direction speciļ¬er next to an explicit control point inherits the direc-

tion of the adjacent path segment. More precisely, ā˜. . z . . controls u and v . .ā™

is treated as if it were ā˜. . {u ā’ z}z . . controls u and v . .ā™ if u = z, or as if it were

ā˜. . {curl 1}z . . controls u and v . .ā™ if u = z. Similarly, ā˜. . controls u and v . . z . .ā™ is

treated as if z were followed by {z ā’ v} if z = v, by {curl 1} otherwise.

After the previous three rules have been applied, we might still be left with

cases in which there are points surrounded on both sides by empty direction

speciļ¬ers. must choose appropriate directions at such points, and it does

so by applying the following algorithm due to John Hobby [Discrete and Computational

Geometry 1 (1986), 123ā“140]: Given a sequence

z0 {d0 } . . tension Ī±0 and Ī²1 . . z1 . . tension Ī±1 and Ī²2 . . z2

etc. znā’1 . . tension Ī±nā’1 and Ī²n . . {dn }zn

Chapter 14: Paths 131

for which interior directions need to be determined, we will regard the zā™s as if they mock curvature

were complex numbers. Let lk = |zk ā’ zkā’1 | be the distance from zkā’1 to zk , and let

Ļk = arg((zk+1 ā’ zk )/(zk ā’ zkā’1 )) be the turning angle at zk . We wish to ļ¬nd direction

vectors w0 , w1 , . . . , wn so that the given sequence can eļ¬ectively be replaced by

z0 {w0 } . . tension Ī±0 and Ī²1 . . {w1 }z1 {w1 } . . tension Ī±1 and Ī²2 . . {w2 }z2

etc. znā’1 {wnā’1 } . . tension Ī±nā’1 and Ī²n . . {wn }zn .

Since only the directions of the wā™s are signiļ¬cant, not the magnitudes, it suļ¬ces to

determine the angles Īøk = arg(wk /(zk+1 ā’ zk )). For convenience, we also let Ļk =

arg((zk ā’ zkā’1 )/wk ), so that

Īøk + Ļk + Ļk = 0. (ā—)

Hobbyā™s paper introduces the notion of āmock curvatureā according to which the fol-

lowing equations should hold at interior points:

2 ā’1 ā’1 2 ā’1 ā’1

Ī²k lk (Ī±kā’1 (Īøkā’1 + Ļk ) ā’ 3Ļk ) = Ī±k lk+1 (Ī²k+1 (Īøk + Ļk+1 ) ā’ 3Īøk ). (ā—ā—)

We also need to consider boundary conditions. If d0 is an explicit direction vector w0 ,

we know Īø0 ; otherwise d0 is ā˜curl Ī³0 ā™ and we set up the equation

ā’1 ā’1

2 2

Ī±0 (Ī²1 (Īø0 + Ļ1 ) ā’ 3Īø0 ) = Ī³0 Ī²1 (Ī±0 (Īø0 + Ļ1 ) ā’ 3Ļ1 ). (ā—ā—ā—)

If dn is an explicit vector wn , we know Ļn ; otherwise dn is ā˜curl Ī³n ā™ and we set

ā’1

2 2 ā’1

Ī²n (Ī±nā’1 (Īønā’1 + Ļn ) ā’ 3Ļn ) = Ī³n Ī±nā’1 (Ī²n (Īønā’1 + Ļn ) ā’ 3Īønā’1 ). (ā—ā—ā— )

It can be shown that the conditions Ī±k ā„ 3/4, Ī²k ā„ 3/4, Ī³k ā„ 0 imply that there is a

unique solution to the system of equations consisting of (ā—) and (ā—ā—) for 0 < k < n plus

the two boundary equations; hence the desired quantities Īø0 , . . . , Īønā’1 and Ļ1 , . . . , Ļn

are uniquely determined. (The only exception is the degenerate case n = Ī³0 Ī³1 = 1.)

A similar scheme works for cycles, when there is no ā˜{d0 }ā™ or ā˜{dn }ā™. In this

case equations (ā—) and (ā—ā—) hold for all k.

EXERCISE 14.8

Write out the equations that determine the directions chosen for the general

cycle ā˜z0 . . tension Ī±0 and Ī²1 . . z1 . . tension Ī±1 and Ī²2 . . z2 . . tension Ī±2 and Ī²3 . . cycleā™

of length 3. (You neednā™t try to solve the equations.)

Whew ā” these rules have determined the directions at all points. To com-

plete the job of path speciļ¬cation, we need merely explain how to change a

segment like ā˜z0 {w0 } . . tension Ī± and Ī² . . {w1 }z1 ā™ into a segment of the form ā˜z0 . .

controls u and v . . z1 ā™ ; i.e., we ļ¬nally want to know ā™s magic recipe for

choosing the control points u and v. If Īø = arg(w0 /(z1 ā’z0 )) and Ļ = arg((z1 ā’z0 )/w1 ),

the control points are

v = z1 ā’ eā’iĻ (z1 ā’ z0 )f (Ļ, Īø)/Ī²,

u = z0 + eiĪø (z1 ā’ z0 )f (Īø, Ļ)/Ī±,

where f (Īø, Ļ) is another formula due to John Hobby:

ā 1 1

2 + 2 (sin Īø ā’ 16 sin Ļ)(sin Ļ ā’ 16 sin Īø)(cos Īø ā’ cos Ļ)

ā ā

f (Īø, Ļ) = .

3 (1 + 1 ( 5 ā’ 1) cos Īø + 1 (3 ā’ 5 ) cos Ļ)

2 2

132 Chapter 14: Paths

Thereā™s yet one more complication. If the tensions Ī± and/or Ī² have been atleast

bounding triangle

preceded by the keyword ā˜atleastā™, the values of Ī± and/or Ī² are increased, if

tension

necessary, to the minimum values such that u and v do not lie outside the ābounding unitsquare

triangle,ā which is discussed near the end of Chapter 3. reverse

What do these complex rules imply, for users who arenā™t āintoā

mathematics? The most important fact is that the rules for paths are invariant

under shifting, scaling, and rotation. In other words, if the key points zk of a path are

all shifted, scaled, and/or rotated in the same way, the resulting path will be the same as

you would get by shifting, scaling, and/or rotating the path deļ¬ned by the unmodiļ¬ed

zk ā™s (except of course for possible rounding errors). However, this invariance property

does not hold if the points or paths are xscaled and yscaled by separate amounts.

Another consequence of the rules is that tension speciļ¬cations have a fairly

straightforward interpretation in terms of control points, when the adjacent

directions have been given: The formulas for u and v simply involve division by Ī± and Ī².

This means, for example, that a tension of 2 brings the control points halfway in towards

the neighboring key points, and a tension of inļ¬nity makes the points very close indeed;

contrariwise, tensions less than 1 move the control points out.

Tension and curl speciļ¬cations also inļ¬‚uence ā™s choices of direc-

tions at the key points. That is why, for example, the construction ā˜zkā’1 - - - zk ā™

(which means ā˜zkā’1 . . tension inļ¬nity . . zk ā™ ) aļ¬ects the direction of a larger path as it

enters zkā’1 and leaves zk .

The rules imply that a change in the position of point zn causes a change

in the curve near point z0 , when has to choose directions at all

points between z0 and zn . However, this eļ¬ect is generally negligible except in the

vicinity of the changed point. You can verify this by looking, for example, at the

control points that chooses for the path ā˜(0, 0) . . (1, 0) . . (2, 0) . . (3, 0) . .

(4, 0) . . . {up }(5, y)ā™, as y varies.

EXERCISE 14.9

Run on the ā˜exprā™ ļ¬le of Chapter 8, and ask to see the path

expression ā˜unitsquare shifted (0, 1) . . unitsquare shifted (1, 0)ā™. Account for the

results that you get.

EXERCISE 14.10

ā™s abbreviation for ā˜{curl 1} . . {curl 1}ā™.

Weā™ve said that ā˜- -ā™ is plain

Would there be any essential diļ¬erence if ā˜- -ā™ were deļ¬ned to mean ā˜{curl 2} . . {curl 2}ā™ ?

EXERCISE 14.11

Look closely at the syntax of path expression and explain what

does with the speciļ¬cation ā˜(0, 0) . . (3, 3) . . cycle{curl 1}ā™.

Now letā™s come back to simpler topics relating to paths. Once a path has

been speciļ¬ed, there are lots of things you can do with it, besides drawing and

ļ¬lling and suchlike. For example, if p is a path, you can reverse its direction by saying

ā˜reverse pā™; the reverse of ā˜z0 . . controls u and v . . z1 ā™ is ā˜z1 . . controls v and u . . z0 ā™.

EXERCISE 14.12

True or false: length reverse p = length p, for all paths p.

Chapter 14: Paths 133

Itā™s convenient to associate ātimeā with paths, by imagining that we move time

subpaths

along a path of length n as time passes from 0 to n. (Chapter 8 has already

mediation

illustrated this notion, with respect to an almost-but-not-quite-circular path called p2; BernshteĖ˜

Ä±n

itā™s a good idea to review the discussion of paths and subpaths in Chapter 8 now before

you read further.) Given a path

p = z0 . . controls u0 and v1 . . z1 etc. znā’1 . . controls unā’1 and vn . . zn

determines ā˜point t of pā™ as follows: If t ā¤ 0, the result

and a number t,

is z0 ; if t ā„ n, the result is zn ; otherwise if k ā¤ t < k + 1, it is (t ā’ k)[zk , uk , vk+1 , zk+1 ],

where we generalize the ā˜t[Ī±, Ī²]ā™ notation so that t[Ī±, Ī², Ī³] means t[t[Ī±, Ī²], t[Ī², Ī³]] and

t[Ī±, Ī², Ī³, Ī“] means t[t[Ī±, Ī², Ī³], t[Ī², Ī³, Ī“]]. (This is a BernshteĖ˜ polynomial in t, cf. Chap-

Ä±n

ter 3.) Given a cyclic path

c = z0 . . controls u0 and v1 . . z1 etc. znā’1 . . controls unā’1 and vn . . cycle

and a number t, determines ā˜point t of cā™ in essentially the same way,

except that t is ļ¬rst reduced modulo n so as to lie in the range 0 ā¤ t < n.

EXERCISE 14.13

True or false: point t of (z0 - - z1 ) = t[z0 , z1 ].

Given a path p and two time values t1 ā¤ t2 , ā˜subpath (t1 , t2 ) of pā™ contains

all the values ā˜point t of pā™ as t varies from t1 to t2 . Thereā™s no problem

understanding how to deļ¬ne this subpath when t1 and t2 are integers; for example,

subpath (2, 4) of p = z2 . . controls u2 and v3 . . z3 . . controls u3 and v4 . . z4

in the notation above, if we assume that n ā„ 4. The fractional case is handled by

āstretching timeā in one segment of the curve; for example, if 0 < t < 1 we have

subpath (0, t) of p = z0 . . controls t[z0 , u0 ] and t[z0 , u0 , v1 ] . . t[z0 , u0 , v1 , z1 ];

subpath (t, 1) of p = t[z0 , u0 , v1 , z1 ] . . controls t[u0 , v1 , z1 ] and t[v1 , z1 ] . . z1 .

These two subpaths together account for all points of ā˜z0 . . controls u0 and v1 . . z1 ā™. To

get subpath (t1 , t2 ) of p when 0 < t1 < t2 < 1, applies this construction

twice, by computing subpath (t1 /t2 , 1) of subpath (0, t2 ) of p.

The operation ā˜subpath (t1 , t2 ) of pā™ is deļ¬ned for all combinations of times

(t1 , t2 ) and paths p by the following rules: Let n = length p. (1) If t1 > t2 ,

subpath (t1 , t2 ) of p = reverse subpath (t2 , t1 ) of p. Henceforth we shall assume that

t1 ā¤ t2 . (2) If t1 = t2 , subpath (t1 , t2 ) of p = point t1 of p, a path of length zero.

Henceforth we shall assume that t1 < t2 . (3) If t1 < 0 and p is a cycle, subpath (t1 , t2 )

of p = subpath (t1 + n, t2 + n) of p. If t1 < 0 and p is not a cycle, subpath (t1 , t2 ) of p =

subpath (0, max(0, t2 )) of p. Henceforth we shall assume that t1 ā„ 0. (4) If t1 ā„ n and

p is a cycle, subpath (t1 , t2 ) of p = subpath (t1 ā’ n, t2 ā’ n) of p. If t1 < n < t2 and p is a

cycle, subpath (t1 , t2 ) of p = subpath (t1 , t2 ) of (p & p & cycle). If t2 > n and p is not a

cycle, subpath (t1 , t2 ) of p = subpath (min(t1 , n), n) of p. Henceforth we shall assume

that 0 ā¤ t1 < t2 ā¤ n. (5) If t1 ā„ 1, subpath (t1 , t2 ) of p = subpath (t1 ā’ 1, t2 ā’ 1) of

subpath (1, n) of p, where subpath (1, n) of p is obtained by removing the ļ¬rst segment

of p. Henceforth we shall assume that 0 ā¤ t1 < 1. (6) If t2 > 1, subpath (t1 , t2 )

of p = subpath (t1 , 1) of p & subpath (1, t2 ) of p. Henceforth we shall assume that

0 ā¤ t1 < t2 ā¤ 1. (7) The remaining cases were deļ¬ned in the preceding paragraph.

134 Chapter 14: Paths

EXERCISE 14.14 postcontrol

ńņš. 16 |