The curves Package^{∗}

Ian Maclaine-cross

                   Internet: i.maclaine-cross@unsw.edu.au

22 August 2000

Abstract Draws curves in the L^{A}TEX 2ε picture environment using parabolas between data points with continuous slope at joins. For circles and arcs uses up to 16 parabolas. Also draws symbols or dash patterns along curves. Equivalent to technical pens with compasses and French curves. Curves consist of short secants drawn by overlapping disks or line drawing \specials selected by package options.

Contents

1 Introduction 2 2 Installation 2 3 Curves 4 4 Scaling 5 5 Symbols 6 6 Dashes 8 7 Errors 9 8 Curves Summary 10

8.1 Loading curves . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 8.2 Arguments of Commands . . . . . . . . . . . . . . . . . . . . . . . 10 8.3 Lengths used by Commands . . . . . . . . . . . . . . . . . . . . . . 10 8.4 Control Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 8.5 Parameter Setting Commands . . . . . . . . . . . . . . . . . . . . . 11 8.6 Curve Drawing Commands . . . . . . . . . . . . . . . . . . . . . . 11

9 How curves Works 12 10 Pleas for the Future 14

∗This file has version number 1.50, last revised 2000/08/22.

11 curves.sty  14

11.1 Registers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 11.2 Boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 11.3 Driver Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 11.4 User Command Definitions . . . . . . . . . . . . . . . . . . . . . . 18 11.5 Drawing Command Details . . . . . . . . . . . . . . . . . . . . . . 19 11.6 Dash Pattern Drawing . . . . . . . . . . . . . . . . . . . . . . . . . 23

12 curvesls.sty  25

1 Introduction

The picture environment in the L^{A}TEX 2ε^{1} macro package for TEX^{2} allows simple line drawing using characters. These characters include quadrant circular arcs, solid disks with diameters from 1 to 15pt^{3} and short lines with a limited range of slopes in two thicknesses. A \begin{picture} command defines an area where following commands place these characters to draw a L^{A}TEX picture.

L^{A}TEX pictures save disk space for source descriptions and computer time in producing documents compared with printer commands or bit mapped graphics. From initial pencil sketch on squared graph paper to final printout, they take half the time for manual pen drawings. The labor savings are higher for revisions and rewrites. Unfortunately standard L^{A}TEX cannot yet draw curves like a pen, compass and French curves can. Fortunately there are many macro packages which supplement L^{A}TEX 2ε’s capabilities and do marvellous graphical things for any printing need^{4}. Curves just adds curve drawing to L^{A}TEX pictures.

Brief descriptions, simple examples and a command summary follow. They presume familiarity with relevant chapters of the L^{A}TEX manual^{1}.

2 Installation

curves.sty To create the file curves.sty you need L^{A}TEX 2ε and a command like:

 $ latex curves.ins

Put curves.sty and curvesls.sty in your default or a texinput directory. The package curvesls provides compatibility for old documents. Comprehensive TEX distributions preinstall curves so for most users the above step is unnecessary.

Put curves in a \usepackage command at the top of your main .tex file for any document where you wish to use curves e.g.,

  \documentclass[11pt]{article}
  \usepackage{curves}

1Leslie Lamport, L^{A}TEX A Document Preparation System 2nd ed., Addison-Wesley, 1994.

2Donald E. Knuth, The TEXbook, Addison-Wesley, 1984.

3A printer’s point, abbreviated pt, is approximately 0.351460 mm.

4Michel Goossens, Frank Mittelbach and Sebastian Rahtz, The LaTeX Graphics Companion, Addison-Wesley, 1997.

BOX

Figure 1: This is a box.

Do not combine curves with bezier in this command. Curves contains a fast powerful replacement for the \bezier command. Drawings using the \bezier command should not change their appearance.

dvips The curves package has options to save TEX memory and runtime using

emtex
xdvi
WML

\special commands to draw the straight lines which approximate curves. Select an option only if your program for viewing or printing TEX’s dvi files recognizes and uses the corresponding \specials. Otherwise the curves on your drawings will be invisible. The dvips option uses the emTEX \specials of dvips which draw lines with rounded ends. The emtex option uses the original \specials of emTEX by Eberhard Mattes with disks added to hide their square ends. The xdvi option uses the PostScript \specials of Tomas Rokicki’s dvips to draw lines which the xdvi viewer now implements. WML are new versions of the emTEX \specials in dvips with compact names. No options draws lines using disks from standard L^{A}TEX fonts. No options or dvips work with the color package but other drivers may or may not. Select package options when required by modifying \usepackage like:

  \usepackage[dvips]{curves}

BOX A drawing frequently uses auxiliary commands to size, place, label and caption it. The following commands draw the box in Figure 1 on page 3:

  \begin{figure}
  \begin{center}
  \setlength{\unitlength}{1mm}
  \begin{picture}(100,50) \large\sf
  \linethickness{1mm}
  \put(20,5){\framebox(60,40){BOX}}
  \end{picture}
  \end{center}
  \caption{This is a box.}
  \label{box}
  \end{figure}

Lamport^{1} explains these commands. This example is for those unfamiliar with the L^{A}TEX picture environment. The following examples avoid the figure environment but it is often essential.

3 Curves

\curve The commands, \curve, \closecurve and \tagcurve, draw parabola segments

\closecurve
\tagcurve

between coordinate points in the argument^{5}. The segments’ tangents at these points are parallel to each other and to straight lines through the points either side. Segments at \curve ends are parabolas with the point second from the end a vertex. \closecurve adds a parabola between end points to close the curve. \tagcurve omits the first and last segments drawing curves with end tangents specified. When only three points are specified \tagcurve draws the last segment. The following table shows these features.

Example  Curve

       [figure: \curve(0,0, 50,100, 100,0)]

       [figure: \closecurve(0,0, 50,100, 100,0)]

        [figure: \tagcurve(100,0, 0,0, 50,100, 100,0, 0,0)]

\arc Axial flow fans often use the RAF 6E aerofoil section. The section coordinates in \curve the following macro come directly from aerodynamic tables^{6}. The \arc commands

draw the leading and trailing radii and the two coordinate \curve the flat chord.

  \newcommand{\RAFsixE}{
    \scaleput(1.25,1.25){\arc(0,-1.25){-135}}
    \scaleput(0,0){\curve(0.366,2.133, 1.25,3.19, 2.5,4.42,
      5.0,6.10, 7.5,7.24, 10,8.09, 15,9.28, 20,9.90, 30,10.3,
      40,10.22, 50,9.80, 60,8.98, 70,7.70, 80,5.91, 90,3.79,
      95,2.58, 99.24,1.52)}
    \scaleput(99.24,0.76){\arc(0,-0.76){180}}
    \scaleput(0,0){\curve(1.25,0, 99.24,0)}
    }

In a picture environment like:

  \begin{picture}(100,20)

5Please see Section 8 for full descriptions of curves commands.

6R.A. Wallis, Axial Flow Fans, Academic Press, 1961, p.335

    \RAFsixE
  \end{picture}

this macro draws:

[figure]

The RAF 6E has a flat undersurface.

\bigcircle The drawing command \bigcircle works similarly to \circle except there is no \circle* equivalent. The following section scales it to an ellipse.

4 Scaling

\unitlength The size of L^{A}TEX picture objects may be uniformly scaled by preceding them with:

\put
  \setlength{\unitlength}{\scale\unitlength}

the desired scale factor \scale is previously defined perhaps with \newcommand as a decimal number. The new coordinates of a point (x′, y′) relative to the current origin are related to the old coordinates (x, y) relative to the same origin by

                          x′ = x × \scale
                          y′ = y × \scale

If a \put(x, y){...} followed the change in \unitlength it would actually put the objects {...} at (x′, y′) Objects defined by \unitlength in {...} would also be larger by \scale. Lamport^{1} describes these commands.

\scaleput  The scale factors \xscale, \xscaley, \yscale and \yscalex are initially de-
\xscale
\xscaley
\yscale
\yscalex

fined to be 1, 0, 1 and 0 respectively but may be redefined to any decimal number using \renewcommand. After they are redefined the new coordinates of a point (x′, y′) relative to the current origin are related to the old coordinates (x, y) relative to the same origin by

                  x′ = x × \xscale + y × \xscaley
                  y′ = x × \yscalex + y × \yscale

If a \scaleput(x, y){...} followed the change in these factors it would actual put the objects {...} at (x′, y′). All the drawing commands in curves use the current values of these four scale factors in placing disks and secants.

These factors can rotate pictures which like \RAFsixE are made solely with curves commands. The factors following rotate the RAF 6E through 12^{∘} clockwise about its (0,0) co-ordinate:

  \renewcommand{\xscale}{0.9781}
  \renewcommand{\xscaley}{0.2079}
  \renewcommand{\yscale}{0.9781}
  \renewcommand{\yscalex}{-0.2079}
  \put(0,20){\RAFsixE}

This draws:

[figure]

The RAF 6E has maximum lift at angles of attack over 12^{∘}.

Note that cos 12^{∘} ≈ 0.9781 and sin 12^{∘} ≈ 0.2079 \arc Axonometric projection is another scaling application. Circles become ellipses

\bigcircle and circular arcs become elliptical arcs. The commands drawing the ellipse and arc in the following washer are:

  \put(20,5){
    \renewcommand{\xscale}{1}
    \renewcommand{\xscaley}{-1}
    \renewcommand{\yscale}{0.6}
    \renewcommand{\yscalex}{0.6}
    \scaleput(10,10){\bigcircle{10}}
    \put(0,-2){
      \scaleput(10,10){\arc(5,0){121}}
      \scaleput(10,10){\arc(5,0){-31}}
      }
    }

(20,5) are the drawing coordinates of the upper vertex of the washer closest to the reader. The angles for the \arcs were found by trial and error.

[figure: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .^{.........}^{.........}^{.........}^{........}^{.......}^{......}^{......}^{......}^{......}^{......}^{......}^{.......}^{........}^{.........}^{.........}^{.........}. . . . . . . . .. . . . . . . . .. . . . . . . . .. . . . . . . .. . . . . . .. . . . . .. . . . . .. . . . . .. . . . . .. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .^{........}^{........}^{........}^{........}^{.......}^{......}^{......}^{.....} . ^{.....} ^{.....} ^{....} ^{....}]

Square washers are sometimes preferred for soft materials.

5 Symbols

\curvesymbol Curves can also place symbols. \curvesymbol must first define the symbol as

\curve anything a \put or \multiput may draw. A negative symbol count between drawing command and coordinates e.g., \tagcurve[-3](0,100,...) fixes the number of symbols per curve segment.

These commands draw flight times and successive positions in the following drawing:

  \newcounter{time}
    \curvesymbol{\thetime\,s\addtocounter{time}{1}}
    \put(5,4){\curve[-2](0,0, 9.8,19.6, 19.6,0)}
    \curvesymbol{\phantom{\circle*{1}}\circle*{1}}
    \put(5,2){\curve[-2](0,0, 9.8,19.6, 19.6,0)}

where \phantom is a plain TEX command from the TEXbook^{2}.

[figure: ^{0 s 1 s 2 s 3 s 4 s}; 0; 5; 10; 15; 20; 25; x (m); 0; 5; 10; 15; 20; 25; y (m)]

Successive positions of a sphere with initial position (5, 2) m, initial velocity (4.9, 9.8) m/s, and acceleration (0, −9.8) m/s^{2}. The flight time is recorded above each sphere position.

\curvedashes Fixed spacing of symbols at lengths other than the segment’s requires more

\curvelength
\curvesymbol

commands. Empty \curvedashes, empty \curvesymbol and negative symbol count stops drawing so a drawing command will calculate \curvelength only. \curvesymbol then resets the symbol and \curvedashes sets the spacing to its pattern length. If there are no symbols at the ends, \overhang pulls symbols along the curve. The last command with no symbol count draws the symbols.

\arc \arc and \bigcircle use sixteen segments for a circle so if eight symbols are \bigcircle required the fixed spacing technique is necessary. The following commands draw

the pin numbers on a relay base:

    \newcounter{pin}
    \curvedashes{}
    \curvesymbol{}
    \put(60,60){\arc[-1](40,0){-360}}
    \setlength{\curvelength}{0.125\curvelength}
    \curvedashes[\curvelength]{1}
    \setlength{\overhang}{0.5\curvelength}
    \curvesymbol{\addtocounter{pin}{1}\thepin}
    \put(60,60){\arc(40,0){-360}}

[figure: . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .^{............}^{.............}^{.............}^{.............}^{............}^{............}^{............}^{............}^{.............}^{.............}^{.............}^{............}^{............}^{.............}^{.............}^{.............}^{............}^{............}^{............}^{............}^{.............}^{.............}^{.............}^{............} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . . .. . . . . . . . . . . .; .. . . .. . . .. . . .. . . .. . . . . . . . . . . .^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}^{....}. . . .. . . .. . . .. . . .. . . .. . . .. . . . . ^{...} ^{...} ^{...} ^{...} ^{...} ^{...} ^{...} ^{...}; ^{1 2 3 4 5 6  7 8}]

The pin numbering of plug-in relays is clockwise from the spigot key when viewed from below.

\patternresolution If symbols and dash pattern exist and \overhang is 0pt, curves draw the first

\overhang position blank. For equal spacing they draw the last position blank if rounding error causes the last pattern to be slightly short. If \renewcommand changes \patternresolution, rounding error changes and the final symbol may reappear. To avoid fiddling with \patternresolution for closed curves with symbols equally spaced, use an \overhang which is a fraction of a pattern length as in the previous example.

6 Dashes

\curvedashes \curvedashes must first define a dash pattern with length greater than 0pt. Many symbol and pattern combinations are possible. The fixed number and fixed spacing methods of symbol drawing described in Section 5 work with three methods of drawing dashes which are:

1. if there is no symbol count and no symbol, a dash pattern with its length reduced by \csdiameter is drawn between symbols spaces of width close to \csdiameter to give an overall spacing equal to the pattern length specified by the \curvedashes command;

2. if there is a symbol count but no symbol, the dash patterns drawn have their length equal to that defined by \curvedashes with \csdiameter gaps at symbol positions;

3. if there is a symbol count and a symbol, the dash patterns drawn have their length adjusted slightly so an integral number of patterns fit between symbol positions.

Dash pattern commands for centrelines^{7} follow for the three techniques above in order:

  \linethickness{0.25mm}
  \curvedashes[1.2mm]{0,8,1,3,1,8}
  \settowidth{\csdiameter}{00}
  \put(0,20){\curve(0,0, 30,5, 60,0)}
  \put(0,10){\curve[1](0,0, 30,5, 60,0)}
  \curvesymbol{\thepin\addtocounter{pin}{1}}
  \setlength{\csdiameter}{2\csdiameter}
  \put(0,0){\curve[1](0,0, 30,5, 60,0)}

The following figure shows the resulting dash patterns. The upper line has first position blank because the \overhang is 0pt. It has patterns shrunk to scale between symbol spaces e.g., 1 to 2, and symbol space centres one pattern length apart. The middle line has patterns close to defined length but with the first dash part blanked by half of symbol space 3 and the second pattern broken in its first dash by symbol space 4. The lower line patterns are stretched between symbol spaces. Which pattern is appropriate depends on picture meaning and function.

7R.N. Roth and I.A. van Haeringen, The Australian Engineering Drawing Handbook, Part 1 Basic Principles and Techniques, The Institution of Engineers, Australia, Canberra, 1986.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ...^{.......................................}.^{...}^{......................}.^{......................}^{..................................................} .^{..........................}^{.................................................}^{. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .^{.....................}.^{......}^{............................}.^{................}^{.....................................................}^{................}.^{......................................}^{..........................................}}^{.} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .^{.}^{.} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .^{.} . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ^{.}^{.................................}^{....................................................}^{....}^{.}^{...............................}^{.}^{................................................} ^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{1  2}^{3  4  5} 6  7  8

Centrelines and Symbols

7 Errors

Syntax errors like incorrect or missing punctuation while using curves will result in TEX or L^{A}TEX error messages. The TEXbook^{2} and L^{A}TEX manual^{1} explain the meaning and correction of these errors. The previous examples and Section 8 should make the correct syntax for curves commands clear.

Curves will write a Package curves Error:... message to the screen and log file if you supply an incorrect number of coordinates.

If four sequential points in a drawing command argument have the line through the first and third parallel to the line through the second and fourth:

• exactly or closely, curves knows it cannot draw a parabola tangent to two parallel lines, issues to the screen and log file:

     Package curve Warning:  \curve straight from ...

and draws a straight line;

• or approximately, curves may draw an unexpected curve with no warning.

If four sequential points in a drawing command argument have the line through the first and second parallel to the line through the third and fourth:

• curves draws a parabola which may be nowhere near the curve.

\curvewarnfalse If the four points were on a straight line, removing one or more points is a remedy. If they are not on a straight line, adding points may help. Specifying many points will give you a satisfactory curve with perhaps an annoying number of \curve straight warnings. After a \curvewarnfalse, curves still uses the straight lines but does not tell you.

\tagcurve Curvature changes sign on curves like y = sin x. Specifying inflection points as curve coordinates will reduce error and specifying sufficient coordinates will then give satisfactory results. For discontinuous tangents splitting a curve into pieces is unavoidable. Splitting a curve into pieces with curvature the same sign can give satisfactory results with fewer coordinates. \tagcurve can prevent tangent discontinuities. If an inflexion point’s exact location is unknown, try the midpoint of the straight line through the ends of its segment.

\diskpitchstretch Curves appear rougher than horizontal and vertical lines. Picture digitization causes this not inaccuracy in TEX or curves.sty. Setting \diskpitchstretch to a value less than one with \renewcommand may smooth an unusually rough curve without package options.

Symbols and symbol spaces misaligned are usually due to rounding error. Adjusting \patternresolution below one can reduce rounding error and increase alignment accuracy. This should be limited to the misaligned curve with { }^{1}.

The replacement \bezier does not give exactly the same results as the original in bezier.sty or in LaTeX2e. The difference is extremely small but if it is important to you comment out the five lines of code for \bezier and \@bezier near the start of curves.sty. You now have a \bezier which is slower and needs more memory but has only its original capabilities and gives only its original results.

Please email i.maclaine-cross@unsw.edu.au examples of any errors not covered above. You may have found a bug in the code or documentation.

8 Curves Summary

The commands following are for the picture environment in the L^{A}TEX 2ε manual^{1}.

8.1 Loading curves

\usepackage A \usepackage{curves} between \documentclass and \begin{document} com-

mands loads curves. If you have a TEX printing or viewing program which accepts the following \special commands you may optionally use them to allow larger pictures faster. Support for color may be lost.

You use \usepackage[⟨option⟩]{curves} to load a \special option for drawing the straight line secants which make curves where ⟨option⟩ is one of:

dvips uses the emTEX \specials with rounded line ends supported by dvips. Works

with color. emtex uses the original emTEX \specials with rectangular line ends. Curves adds a disk

to round them. xdvi uses the PostScript \specials of dvips. WML the same as dvips but with single character names W, M and L to minimize TEX

memory with large pictures.

8.2 Arguments of Commands

⟨blank length ⟩ decimal number of ⟨unit len⟩ blanks. Not negative.

⟨character or symbol ⟩ is anything which a \put or \multiput may draw.

⟨coordinates ⟩ are decimal numbers giving alternate x and y coordinates of the curve as multiples

of \unitlength, comma separated.

⟨[,dash...] ⟩ optional continuation of alternating dash and blank numbers of unit lengths,

comma separated. Not negative. Allows decimal points.

⟨diameter ⟩ is a decimal number giving the diameter in \unitlengths. ⟨symbol count ⟩ is the number of symbols or patterns to be drawn, default 0.

⟨unit len ⟩ unit length dimension e.g., 2.5mm, 10pt, used in measuring blanks and dashes. Not negative. Default value is \unitlength.

8.3 Lengths used by Commands

\csdiameter is the size of the space left for a symbol and can be increased or set with

\settowidth{\csdiameter}{⟨character or symbol⟩}.

\curvelength is the total length of the curve calculated before drawing by using Simpson’s rule

once between each pair of coordinate points.

\overhang length of as drawn dash pattern overlapping start of patterns.

8.4 Control Commands

\curvewarntrue turns warning of parabola replacement by straight lines on (default). \curvewarnfalse turns warning of parabola replacement by straight lines off.

8.5 Parameter Setting Commands

\curvesymbol {⟨character or symbol⟩} sets symbol and \csdiameter. \curvedashes [⟨unit len⟩]{⟨blank length⟩⟨[,dash...]⟩} A drawing command not following a

\curvedashes or following one with an empty or zero length pattern will draw:

if ⟨symbol count⟩ is zero or missing, a continuous curve;

else if ⟨symbol count⟩ is positive, ⟨symbol count⟩-1 squares of line thickness size between and additional squares at coordinates or bezier end points;

else if no ⟨character or symbol⟩ exists, nothing;

else, -⟨symbol count⟩-1 characters or symbols between coordinates and additional ones at coordinates or bezier end points.

After a \curvedashes command defining a pattern whose length exceeds zero, commands draw:

if ⟨symbol count⟩ is zero or missing then at a spacing equal to the specified pattern length,

if no ⟨character or symbol⟩ exists, a dash pattern reduced in length by

\csdiameter to fit between symbol spaces of \csdiameter, else if \overhang is not 0pt, a ⟨character or symbol⟩ at all positions, else a ⟨character or symbol⟩ with the first position blank;

else, \csdiameter wide symbol spaces, one at and ⟨symbol count⟩-1 between coordinate points with dash pattern lengths,

if no ⟨character or symbol⟩ exists, exact but broken by the spaces, else, adjusted to give a whole number of patterns between spaces.

\diskpitchstretch is initially 1 but \renewcommand can change it to a higher value like 5 to save memory in drafts of complex documents or a lower local value like 0.5 to smooth curve digitization.

\linethickness {⟨len⟩} sets line or dash thicknesses to ⟨len⟩ from 0.5pt up to 15pt (0.17mm to

5mm). \thicklines and \thinlines also set thickness.

\patternresolution is initially 1 but \renewcommand can change it to a higher value like 5 to save memory in drafts of complex documents or a lower local value like 0.5 for greater dash pattern accuracy.

\xscale are scale factors initially set to 1, 0, 1 and 0 respectively which \renewcommand

\xscaley
\yscale
\yscalex

can reset.

8.6 Curve Drawing Commands

Curves drawn consist of parabolic arcs between coordinate points with tangents at each point parallel to the straight line through adjacent points.

\arc [⟨symbol count⟩](X1,Y1){⟨angle⟩} draws a circular arc centred on current posi-

tion, starting from (X1,Y1) and proceeding counterclockwise for ⟨angle⟩ degrees.

\bezier {⟨symbol count⟩}(X1,Y1)(X2,Y2)(X3,Y3) draws a curve through the end points (X1,Y1) and (X3,Y3) tangent to the straight lines joining each of them to (X2,Y2). Extended faster replacement for bezier.sty version.

\bigcircle [⟨symbol count⟩]{⟨diameter⟩} draws a circle of diameter equal to ⟨diameter⟩ times

\unitlength.

\closecurve [⟨symbol count⟩](⟨coordinates⟩) draws a closed curve with continuous tangents

at all points. At least 6 coordinates required. \curve [⟨symbol count⟩](⟨coordinates⟩) draws a curve through the ⟨coordinates⟩ speci-

fied. For 4 coordinates this is a straight line.

\scaleput (X1,Y1){⟨picture object⟩} places a picture object in a position scaled by \xscale,

\xscaley, \yscale and \yscalex for axonometric projection or rotations.

\tagcurve [⟨symbol count⟩](⟨coordinates⟩) draws a curve without its first and last segments but if only 6 coordinates draws the last segment only.

9 How curves Works

Superimposing characters closely can draw any curve. Disks give directional independence of line thickness and visual smoothness at large pitch. Smoothness increases with output resolution but is almost independent of disk pitch below a critical maximum. The following table suggests this maximum varies from 0.34pt for an 0.5pt thick curve to 3pt for a 15pt curve.

Thickness Magnified Comments  Line at 1/6 slope
[figure: 15pt; ×1; 1pt pitch disks]
[figure: 15pt; ×1; 3pt pitch disks]
[figure: ≈0.5pt; ×1; L^{A}TEX \line(6,1)]
≈0.5pt  ×1  0.34pt pitch disks  .^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}^{.}
≈0.5pt ×30

0.34pt pitch disks resolution ×30

[figure]

L^{A}TEX \line^{1} or line drawing \special commands require a tenth the TEX memory so are preferable to disks if available. L^{A}TEX can load TEX^{8} macros from package files with a .sty extension. These macros can calculate the disk or line positions for a curve.

The difference in the changes in position between successive pairs of disks may be so small that TEX rounding causes visible curve error. The difference between a curve and straight secants joining points many disks apart can be invisible with invisible TEX rounding also. TEX can efficiently draw visibly accurate curves as a sequence of straight secants. Straight line drawing \specials are often incompatible so multiple line options are desirable in macros. A smooth curve may require thousands of disks but only hundreds of secants so line \specials may prevent a complex drawing from overflowing TEX memory.

curves.sty provides macro commands for drawing curves as secants. Version 1.50 loads in about 2000 words^{9} of TEX’s main memory, which allows a small TEX.

8Donald E. Knuth, The TEXbook, Addison-Wesley, 1984, Chapter 20.

9A character or token takes a TEX word, 32 bits or larger.

Complex or numerous floating drawings still require a big TEX with curves.sty. Current options for line \specials are dvips, emtex, xdvi, and WML.

The capabilities of these macros are:—

• A compatible replacement for \bezier^{10} from bezier.sty or L^{A}TEX 2ε.

• Work with slides class for overhead transparencies with L^{A}TEX 2ε^{11}.

• Curves have the minimum number of disks or secants for visual smoothness.

• Curve thickness adjustable from 0.5 to 15pt (0.17 to 5mm).

• Curves have continuous slope.

• Curves for any number of points greater than one using \curve.

• Control of end slopes using \tagcurve.

• Closed curves with continuous slope using \closecurve.

• Large circles \bigcircle and circular arcs \arc.

• Independent scaling of curve abscissa and ordinates to fit graphs.

• Affine scaling for making arcs or circles elliptical.

• Symbols and dash patterns combined without interference.

• Any dash length or spacing.

• Three methods for fitting dash patterns to curves.

Parabolas approximate the segments between the specified coordinate points. At an internal curve point, the slope of the two parabolas which join is the slope of the straight line joining the adjacent points. For an end segment, the inside point of the parabola is made a vertex which determines the slope of the end point. \tagcurve has hidden end segments which allows complete control of slope at the visible end point when desired. This scheme makes the curves and slopes continuous and the discontinuity in curvature is small with sufficient data points.

Usually four points determine the parabola segment between the two inside points. The four points could be close to a straight line or consistent with an inflexion point. A straight line then replaces the parabola between the inside points and optionally a warning is issued.

Each parabola is drawn as a series of short secants. For line \specials, the dvi driver draws the straight lines. Otherwise, the secants are drawn as overlapping disks at high speed using a simple tail chasing macro. This macro’s arithmetic calculations are two fixed point additions per disk drawn.

For circles and circular arcs, a parabola approximates an arc segment no more than 23^{∘} giving a radius increase between segment ends less than 0.02%. A full circle uses 16 parabolas. The error in computing and multiplying by sine and cosine is usually less than 0.01% of the radius at the far end of an arc.

10See your Local Guide. Try the system command latex local to get a L^{A}TEXed Guide.

11Michel Goossens, Frank Mittelbach and Alexander Samarin, The L^{A}TEX Companion, Addison-Wesley, 1994.

10 Pleas for the Future

Curves will never work with plain TEX and it will never be as powerful as META-FONT or importing encapsulated PostScript files. Suggestions or criticisms by email are welcome. Version 1.50 has benefitted greatly from previous help. The latest versions are first available at URL:

 ftp://ilm.mech.unsw.edu.au/pub/archive/latex/macros/curves/

At your local CTAN mirror the latest version should be near the directory for the latest version of L^{A}TEX. Please use CTAN to reduce Internet load.

WML A .dvi file containing curves produced with the emtex option has many oc-

currences of the text strings em:lineto, em:moveto and em:linewidth XXXXpt

placed by the emTEX \specials. These strings would have earlier occupied TEX memory. Extra memory is also taken by the disks used to cover the cracks between square line ends at a slight angle. Renaming these \specials to L, M and W XXXXpt respectively would save TEX memory. Even better, W XXXXpt could calculate and store the bitmap of a disk which L would add to its line ends to round them so curves need not add disks^{12}. If you write dvi drivers, please add these three proposed \specials.

11 curves.sty

The description of the algorithms following is minimal. Future releases will add more.

1 ⟨∗package⟩

Make ‘;’ appear like a letter so control sequences can use it and they will not be accidently used by other macro packages.

 2 \catcode`\;=11

3

11.1 Registers

Counts number of symbols on Bezier segment

 4 \newcount\;sc
 5 \newcount\;scp
 6 \newcount\;t

coordinate count

 7 \newcount\;cc

actual point count to next dot

 8 \newcount\;cnd

maximum point count to next dot

 9 \newcount\;mcnd
10 \newcount\;np
11 \newcount\;overhang
12 \newcount\;pbs
13 \newcount\;pns

12dvips’s emTEX \specials round line ends but not all emTEX \specials do.

maximum dot spacing on line in sp.

14 \newcount\;psc
15 \newcount\;rc
16 \newcount\;rtc
17 \newcount\;tc
18 \let\;tca=\@tempcnta
19 \let\;tcb=\@tempcntb

20

Dimens

21 \newlength\csdiameter
22 \newlength\curvelength
23 \newlength\overhang
24 \newlength\;x
25 \newlength\;dx
26 \newlength\;ddx
27 \newlength\;y
28 \newlength\;dy
29 \newlength\;ddy
30 \newlength\;pl
31 \newlength\;ucd
32 \let\;td=\@tempdima
33 \let\;ytd=\@tempdimb

34

Boxes

35 \newsavebox{\;csbox}
36 \newsavebox{\;pt}

37

11.2 Boolean

has an option been selected

38 \newif\if;noopt  \;noopttrue

Warn about curve problems

39 \newif\ifcurvewarn \curvewarntrue

coordinate number correct

40 \newif\if;ccn

plot points if true

41 \newif\if;pt

curve symbol defined

42 \newif\if;csym

symbol or pattern count

43 \newif\if;scnt

44

help strings

45 \newhelp\;strline{curve straight from}
46 \newhelp\m;ssingcoord{curve needs more points, add them.}
47 \newhelp\;negdash{curvedashes needs the same sign for all arguments.}
48 \newhelp\;oddcoord{curve requires two co-ordinates for each point,
49 count them.}

50

11.3 Driver Options

The following three commands may be reset by curves options to contain straight line drawing \specials which some dvi drivers may have. The usual default for unimplemented \specials is the driver draws nothing. If no option is specified L^{A}TEX period and circle fonts are used to plot straight lines segments efficiently. This should always work with L^{A}TEX 2ε. The resulting curves differ in run time, TEX memory use, .dvi and printer file size but not in output pictures. Sets the line width

51 \newcommand\;linewidth[1]{}

Sets the start of the line

52 \newcommand\;startline{}

Draws the line and sets next start.

53 \newcommand\;stopl;ne{}

54

55 \newcommand\;optioncheck[2]{%
56 \DeclareOption{#1}{%
57  \if;noopt
58  #2\;nooptfalse
59  \else
60  \PackageError{curves}{Option
61  \CurrentOption\space ignored}{curves uses only one dvi option}%
62  \fi
63 }%

64 }

65

Sets thickness and no disk character for rounded line ends.

66 \newcommand\;setdisk{\@killglue \;linewidth\@wholewidth
67 \set;pt{}\let\;stopline\;stopl;ne}
68 \newcommand\s;tpitch{\;td\patternresolution\p@ \;psc\;td}

69

70 \;optioncheck{dvips}{

Works with the color package.

71 \renewcommand\;linewidth[1]{\special{em:linewidth \the#1}}%
72 \renewcommand\;startline{\special{em:moveto}}%
73 \renewcommand\;stopl;ne{\special{em:lineto}}%

74 }

75

76 \;optioncheck{emtex}{
77 \renewcommand\;linewidth[1]{\special{em:linewidth \the#1}}%
78 \renewcommand\;startline{\special{em:moveto}}%
79 \renewcommand\;stopl;ne{\special{em:lineto}}%
80 \renewcommand\;setdisk{\@killglue
81  \ifdim\@halfwidth>\p@
82  \set;pt{\@circ\@wholewidth{112}}\;linewidth{\wd\;pt}%
83  \s;tcirc{\unhbox\;pt}%
84  \else \;linewidth\@wholewidth \set;pt{}\fi \let\;stopline\;stopl;ne}

85 }

86

87 \;optioncheck{xdvi}{

Works with xdvi and dvips but not color.

Divide the excess precision of scaled points by 256 to save TEX memory and dvi file size. Device independent for resolutions smaller than 18501 dots per inch. Note: 72.27 × 256/72 = 256.96 exactly so errors occur only after the \divides in

 the \;stopl;ne.
 88 \special{!/;L{1 256.96 div dup scale 1 setlinecap
 89  setlinewidth newpath 0 0 moveto lineto stroke}def}%
 90 \newcount\;wc
 91 \newlength\;X
 92 \newlength\;Y
 93 \renewcommand\;linewidth[1]{\;wc#1}%
 94 \renewcommand\;startline{\global\;X\;x \global\;Y\;y}%
 95 \renewcommand\;stopl;ne{%
 96  \;tca\;X \advance\;tca-\;x \;tcb\;Y \advance\;tcb-\;y
 97  \divide\;tca\@cclvi \divide\;tcb\@cclvi \divide\;wc\@cclvi
 98  \special{"\the\;tca\space \the\;tcb\space \the\;wc\space ;L}%
 99  \;startline

100 }% 101 }

102

103 \;optioncheck{WML}{
104 \renewcommand\;linewidth[1]{\special{W \the#1}}%
105 \renewcommand\;startline{\special{M}}%
106 \renewcommand\;stopl;ne{\special{L}}%
107 \;nooptfalse

108 }

109

110 \let\;optioncheck\relax
111 \ProcessOptions\relax

112

113 \if;noopt

114

115 \newcount\;wc
116 \newlength\;X
117 \newlength\;Y

118

119 \newcommand\;setperiod{\;tcb
120 \ifdim\@halfwidth>.6\p@ 17\;td.7
121 \else \ifdim\@wholewidth>.85\p@ 12\;td.48
122  \else \ifdim\@wholewidth>.6\p@ 8\else 5\fi \;td.34
123  \fi
124 \fi \p@
125 \s;tcirc{\rm \fontseries m\fontshape n\fontsize{\the\;tcb}\p@
126  \selectfont \hss.}}%

127

Sets LaTeX disk character and calculates maximum spacing or selects period.

128 \renewcommand\;setdisk{\@killglue \ifdim\@halfwidth>.85\p@
129  \s;tcirc{\@circ{\@wholewidth}{112}}\;td\@wholewidth
130  \divide\;td 8\advance\;td.6\p@ \ifdim\;td>\thr@@\p@\;td\thr@@\p@\fi
131 \else \;setperiod \fi \let\;stopline\;stopl;ne}%

132

133 \renewcommand\s;tpitch{\;ytd\diskpitchstretch\;td \;wc\;ytd
134 \;td\patternresolution\p@ \;psc\;td }

136 \renewcommand\;startline{\global\;X\;x \global\;Y\;y}

137

138 \renewcommand\;stopl;ne{%

This plots just the intermediate disks of a straight line segment which requires any. The end disks are plotted in the device independent code.

139 \;td\;X \advance\;td-\;x \;ytd\;Y \advance\;ytd-\;y
140 \;startline \;rxya\;td\;ytd \divide\;rc\;wc
141 \ifnum\;rc>\z@ \advance\;rc\@ne
142  \divide\;td\;rc \divide\;ytd\;rc \;y\z@
143  \advance\;rc\m@ne \;tca\;rc
144  \let\n;xt\;ls \;ls \kern-\;rc\;td
145 \fi}

146

147 \newcommand\;ls{\advance\;y\;ytd \kern\;td \raise\;y\copy\;pt
148 \advance\;tca\m@ne \ifnum\;tca=\z@ \let\n;xt\relax \fi \n;xt}

149

150 \fi

151

11.4 User Command Definitions

152 \newcommand\arc[1][0]{\;arc[#1]}
153 \newcommand\;arc{}
154 \def\;arc[#1](#2,#3)#4{\;setpoint{#1}\scaleput(#2,#3){\;ddx
155 -#3\unitlength \;ddy#2\unitlength \;firstpoint \;td#4\p@ \;drwarc}}

156

Redefines version in LaTeX 2e of 1 June 1994.

157 \def\bezier#1)#2(#3)#4({\@bezier#1)(#3)(}
158 \def\@bezier#1(#2,#3)(#4,#5)(#6,#7){\;dx#4\unitlength \;ddx-\;dx
159 \advance\;dx-#2\unitlength \advance\;ddx#6\unitlength
160 \;dy#5\unitlength \;ddy-\;dy \advance\;dy-#3\unitlength
161 \advance\;ddy#7\unitlength
162 \;setpoint{#1}\scaleput(#2,#3){\;firstpoint \;bezier}}

163

164 \newcommand\bigcircle[2][0]{\;setpoint{#1}\;dx\unitlength
165 \global\divide\unitlength\tw@
166 \scaleput(#2,0){\;startline \;ddx\z@ \;ddy#2\unitlength
167 \global\unitlength\;dx \;td360\p@ \;drwarc}}

168

169 \newcommand\closecurve[1][0]{\;closecurve[#1]}
170 \newcommand\;closecurve{}
171 \def\;closecurve[#1](#2){\;coordn\closecurve\thr@@{#2}{#1}%
172 \if;ccn\scaleput(\;xb,\;yb){\;startline
173  \edef\;ci{\;xa,\;ya,#2,\;xb,\;yb,\;xc,\;yc}%
174  \advance\;cc\thr@@ \;tagcurve\;ci}\fi}

175

176 \newcommand\curve[1][0]{\;curve[#1]}
177 \newcommand\;curve{}
178 \def\;curve[#1](#2){\;coordn\curve\tw@{#2}{#1}%
179 \if;ccn \scaleput(\;xa,\;ya){\;firstpoint
180  \ifnum\;cc=\tw@ \;slbezd \;slbez
181  \else \;scbezd\;dx\;ddx\;xa\;xb\;xc \;scbezd\;dy\;ddy\;ya\;yb\;yc

182  \;bezier \;tagcurve{#2}\ifnum\;cc>6\;endcurve\fi \fi}\fi}
183 \newcommand\;scbezd[5]{\;slcd#2#3#5\divide#24\;slcd#1#3#4\advance#1-#2}
184 \newcommand\;xa{} \newcommand\;xb{} \newcommand\;xc{}
185 \newcommand\;ya{} \newcommand\;yb{} \newcommand\;yc{}
186 \newcommand\;ci{}

187

188 \newcommand\curvesymbol[1]{\def\;curvesymbol{#1}\ch;ckcs
189 \global\sbox\;csbox{#1}\csdiameter\wd\;csbox}
190 \newcommand\;curvesymbol{} \def\;curvesymbol{}

191

192 \newcommand\curvedashes[2][\unitlength]{\;ucd#1\def\;icurvedashes{#2}%
193 \;ccnfalse \;pl\z@
194 \@for \;ci:=#2\do{\ifdim\;ci\;ucd<\z@ \;ccntrue
195  \PackageError{curves}{\string
196  \curvedashes\space sign bad at \;ci\MessageBreak}{\the\;negdash}%
197  \else \advance\;pl\;ci\;ucd \fi}\if;ccn\;pl\z@\fi}
198 \newcommand\;icurvedashes{}

199

200 \newcommand\tagcurve[1][0]{\;tgcrv[#1]}
201 \newcommand\;tgcrv{}
202 \def\;tgcrv[#1](#2){\;coordn\tagcurve\thr@@{#2}{#1}\if;ccn
203 \scaleput(\;xb,\;yb){\;firstpoint \;tagcurve{#2}}\fi}

204

205 \newcommand\scaleput{}
206 \long\def\scaleput(#1,#2)#3{\@killglue \;td#2\unitlength
207 \raise\yscale\;td \hbox to \z@{\kern\xscaley\;td \;td#1\unitlength
208 \kern\xscale\;td \raise\yscalex\;td \hbox{#3}\hss}\ignorespaces}
209 \newcommand\xscale{\@ne}
210 \newcommand\xscaley{0}
211 \newcommand\yscale{\@ne}
212 \newcommand\yscalex{0}

213

214 \newcommand\diskpitchstretch{\@ne}
215 \newcommand\patternresolution{\@ne}

216

11.5 Drawing Command Details

Plot first point if any.

217 \newcommand\;firstpoint{\;startline \ifdim\;pl=\z@\;point\relax\fi}

218

Calculates segment count, sine, cosine and differences then plots segments.

219 \newcommand\;drwarc{\;cc\;td \;np\;td \;td23\p@ \divide\;cc\;td
220 \;abs\;cc \advance\;cc\@ne \;pns\p@ \divide\;pns\tw@
221 \divide\;np\;cc \;rc\;np \divide\;rc\;pns \;abs\;rc
222 \advance\;rc\@ne \divide\;np\;rc \multiply\;np\;pns \divide\;np14668 %
223 \multiply\;np\;rc \divide\;np\@cclvi \;scp\p@ \multiply\;scp\@cclvi
224 \;t\;pns \;csi\;csi\;csi\;csi \;rxya\;ddx\;ddy \divide\;rc\p@
225 \advance\;rc\@ne \;rtc\;rc \advance\;rc\;rc \;ndd\;ddx \;ndd\;ddy
226 \;csi \;rxya\;ddx\;ddy \divide\;rc\;pns \advance\;rc\@ne
227 \@whilenum\;cc>\z@ \do{\advance\;cc\m@ne \;dx\;ddx \;dy\;ddy
228  \divide\;ddx\;rc \divide\;ddy\;rc \;td\;ddx \;ddx\;t\;td
229  \advance\;ddx-\;np\;ddy \;ddy\;t\;ddy \advance\;ddy\;np\;td
230  \divide\;ddx\;pns \divide\;ddy\;pns \;ddx\;rc\;ddx \;ddy\;rc\;ddy

231  {\;bezier \global\;td\;x \global\;ytd\;y
232  \global\;tca\;overhang}\;y\;ytd \;x\;td \;overhang\;tca}}
233 \newcommand\;ndd[1]{\divide#1\;rc \multiply#1\;np
234 \divide#1\;t #1\;rtc#1}

Cosine and sine half angle iteration.

235 \newcommand\;csi{\;tcb\;np \multiply\;np\;t \divide\;np\;pns \;t\;tcb
236 \multiply\;t\;t \divide\;t-\;scp \advance\;t\;pns \divide\;scp4 }

237

Count the number of coordinates specified and warn if incorrect.

238 \newcommand\;coordn[4]{\;setpoint{#4}\ifx#1\closecurve\;cc\tw@
239 \else\;cc\z@\fi
240 \@for\;ci:=#3\do{\advance\;cc\@ne
241  \ifcase\;cc \or \;d;f\;xa \or \;d;f\;ya \or \;d;f\;xb
242  \or \;d;f\;yb \or \;d;f\;xc \or \;d;f\;yc \fi
243  \ifx#1\closecurve\ifodd\;cc \;d;f\;xa \else \;d;f\;ya \fi\fi}%
244 \;ccnfalse \ifx#1\closecurve \advance\;cc-\tw@ \fi
245 \ifodd\;cc
246  \PackageError{curves}{\string #1\space points odd}{\the\;oddcoord}%
247 \else \divide\;cc\tw@
248  \ifnum#2>\;cc \PackageError{curves}{\string #1\space needs \the#2
249  points\MessageBreak}{\the\m;ssingcoord}%
250  \else \;ccntrue \fi\fi}

251

Sets symbol, character or disk depending on how line is to be plotted. Corrects overhang to be positive or zero but no greater than \;pl.

252 \newcommand\;setpoint[1]{\curvelength\z@ \let\;stopline\relax
253 \def\;point##1{\raise\;y\hbox{{\copy\;pt##1}}}\ch;ckcs
254 \ifnum#1=\z@\;scntfalse\else\;scnttrue\fi
255 \;sc#1\relax \;abs\;sc \;psc\;sc
256 \ifdim\;pl>\z@ \;overhang\overhang
257  \ifnum\;overhang=\z@\else \;np\;overhang
258  \divide\;np\;pl \multiply\;np\;pl
259  \ifnum\;overhang<\z@ \advance\;overhang\;pl
260  \else \ifnum\;overhang=\;np\advance\;overhang\;pl\fi
261  \fi \advance\;overhang-\;np \fi
262  \if;csym \if;scnt\;setdisk\else\;setsymbol\fi
263  \else \;setdisk \fi\s;tpitch
264 \else\ifnum#1>\z@
265  \s;tcirc{\hss\vrule\@height\@wholewidth\@width\@wholewidth}%
266 \else\ifnum#1<\z@ \if;csym\;setsymbol\else\set;pt{}\fi
267 \else\;setdisk\s;tpitch
268 \fi\fi\fi \;x\z@ \;y\dp\;pt \advance\;y-\ht\;pt \divide\;y\tw@}
269 \newcommand\;setsymbol{\s;tcirc{\hss\unhcopy\;csbox}%
270 \edef\;point{\;point\relax
271 \s;tcirc{\hss\noexpand\;curvesymbol}\global\setbox\;csbox\copy\;pt}}
272 \newcommand\;stopline{} \newcommand\;point{}

273

Check if curvesymbol exists and set switch.

274 \newcommand\ch;ckcs{\ifx\;curvesymbol\@empty\;csymfalse
275 \else\;csymtrue\fi}

276

Makes zero width box \;pt of point

277 \newcommand\s;tcirc[1]{\set;pt to\z@{#1\hss}}

278

Set global box \;pt

279 \newcommand\set;pt{\global\setbox\;pt\hbox}

280

Plots last segment of curve from coordinates already read.

281 \newcommand\;endcurve{\;ecbezd\;dx\;ddx\;xa\;xb\;xc
282 \;ecbezd\;dy\;ddy\;ya\;yb\;yc \;bezier}
283 \newcommand\;ecbezd[5]{\;slcd#1#3#5\divide#14
284 #2-#1\advance#2#5\unitlength
285 \advance#2-#4\unitlength}

286

Reads coordinates of four points before going to difference calculation.

287 \newcommand\;tagcurve[1]{\ifnum\;cc=\thr@@ \;endcurve \else \;cc\z@
288 \@for\;ci:=#1\do{\advance\;cc\@ne \ifnum\;cc>6 %
289  \ifodd\;cc \;slcd\;dx\;xa\;xc \let\;xa\;xb \let\;xb\;xc \;d;f\;xc
290  \else \t;gcrv \fi \fi}\fi}

291

Calculates differences over whole segment from four points.

292 \newcommand\t;gcrv{\;slcd\;dy\;ya\;yc
293 \let\;ya\;yb \let\;yb\;yc \;d;f\;yc
294 \;rxy\;dx\;dy \divide\;dx\;rtc \divide\;dy\;rtc
295 \;ddx-\;ya\;dx \advance\;ddx\;xa\;dy \;ddy\;ddx
296 \advance\;ddx\;yb\;dx \advance\;ddx-\;xb\;dy
297 \advance\;ddy\;yc\;dx \advance\;ddy-\;xc\;dy
298 \;slbezd \;td\;ddy \divide\;td\@m
299 \ifdim\;td=\z@ \ifcurvewarn
300  \PackageWarning{curves}{\the\;strline\MessageBreak
301  \;xa,\;ya\space to \;xb,\;yb\MessageBreak}\fi
302  \;slbez
303 \else \;td\unitlength \;rtc\;td \advance\;rtc\;rtc
304  \divide\;rtc\p@ \advance\;rtc\@ne \divide\;td\;rtc
305  \;t\;ddx \;scp\;t \;abs\;t
306  \advance\;t\;t \divide\;t\p@ \advance\;t\@ne \divide\;scp\;t
307  \multiply\;td\;scp \divide\;td\;ddy
308  \multiply\;td\;rtc \multiply\;td\;t
309  \;ddx\;xc\;td \advance\;ddx-\;xa\;td \advance\;dx-\;ddx
310  \;ddy\;yc\;td \advance\;ddy-\;ya\;td \advance\;dy-\;ddy
311  \;bezier \fi}

312

Avoid repeating {\;ci}

313 \newcommand\;d;f[1]{\edef#1{\;ci}}

314

315 \newcommand\;slbezd{\;slcd\;dx\;xa\;xb \;slcd\;dy\;ya\;yb}

316

Calculates difference between two coordinates.

317 \newcommand\;slcd[3]{#1#3\unitlength \advance#1-#2\unitlength}

318

Calculates differences for bezier straight line.

319 \newcommand\;slbez{\divide\;dx\tw@ \;ddx\;dx \divide\;dy\tw@
320 \;ddy\;dy \;bezier}

321

Scales segment differences, then calculates segment pattern and disk count, and initial disk differences; selects line or dashes. Dash patterns were originally measured out in multiples of the disk pitch and are currently in points but can be adjusted with \patternresolution. This should be reprogrammed in scaled points.

322 \newcommand\;bezier{\;scale\;dx\;dy \;scp\;rc \;scale\;ddx\;ddy
323 \advance\;scp\;rc \;bezc\;dx\;ddx \;bezc\;dy\;ddy  \;rxy\;ddx\;ddy
324 \divide\;rc\p@ \advance\;rc\thr@@
325 \;tc\;rc \ifnum\;rc>\sixt@@n\;rc\sixt@@n\fi
326 \;rroot\;rroot\;rroot\;rroot
327 \;t\;rc \;rxy\;dx\;dy \advance\;rc\;scp \divide\;rc\thr@@
328 \global\advance\curvelength\;rc sp\;mcnd\@ne

Here \;t is the number of straight line segments making current bezier segment and \;rc is the length of the bezier segment in scaled points.

329 \ifdim\;pl>\z@ \;np\;rc \divide\;np\;psc
330  \ifnum\;t<\;np \;mcnd\;np \divide\;mcnd\;t
331  \divide\;np\;mcnd \multiply\;np\;mcnd \;t\;np
332  \fi
333 \fi
334 \if;scnt
335  \ifdim\;pl=\z@ \;t\;sc
336  \else \;np
337  \if;csym \;rc \divide\;np\;sc \advance\;np-\csdiameter
338  \;td\;pl \divide\;td\tw@ \advance\;np\;td \divide\;np\;pl
339  \ifnum\;np<\@ne\;np\@ne\fi \multiply\;np\;sc
340  \else \;sc
341  \fi
342  \advance\;t\;np \divide\;t\;np \multiply\;t\;np
343  \fi
344 \fi

Here \;mcnd is the number of pattern increments in a straight segment and \;t in the bezier segment. \;np is the number of complete patterns when known.

The calculation following ensures that the end point of the bezier curve is as accurate as possible.

345 \;rtc\;t \divide\;rtc\;mcnd \;tcb\;rtc \multiply\;tcb\;t
346 \advance\;rtc\m@ne \multiply\;rtc\;t \;tc\;t \advance\;tc\;tc
347 \;bezd\;dx\;ddx \;bezd\;dy\;ddy
348 \ifdim\;pl>\z@ \;dashes \else \let\n;xt\;spoints \;spoints \fi}
349 \newcommand\;scale[2]{\;td\xscale#1\advance\;td\xscaley#2%
350 #2\yscale#2\advance#2\yscalex#1#1\;td \;rxy#1#2}
351 \newcommand\;bezc[2]{\advance#1#1\advance#2#2%
352 \;td#2\advance#2-#1\advance#1\;td}
353 \newcommand\;bezd[2]{\divide#2\;tcb \;td#2\multiply\;td\;rtc
354 \advance#1-\;td \divide#1\;tc}

355

Plots a continuous line or equispaced squares or symbols along a segment.

356 \newcommand\;spoints{\advance\;y\;dy \advance\;x\;dx \kern\;dx
357 \;point\;stopline \advance\;t\m@ne

358 \ifnum\;t>\z@ \advance\;dx\;ddx \advance\;dy\;ddy
359 \else \let\n;xt\relax \fi \n;xt}

360

Calculates length of vector \;rc from coordinates #1, #2

361 \newcommand\;rxy[2]{\;rxya#1#2%
362 \ifnum\;rc>\z@ \;rtc\;rc \advance\;rtc\;rtc \divide\;rtc\p@
363  \ifnum\;rtc>\z@ \advance\;rtc\@ne \divide\;tc\;rtc
364  \divide\;tcb\;rtc \divide\;rc\;rtc
365  \else \;rtc\@ne
366  \fi
367  \multiply\;tc\;tc \multiply\;tcb\;tcb
368  \advance\;tc\;tcb \;rroot\;rroot \multiply\;rc\;rtc
369 \fi}

370

Estimate length of vector \;rc from coordinates #1, #2. For 1 > |x| ≥ |y| > 0, |x| + |y|/3 is within 6% of \sqrt{x^{2} + y^{2}}.

371 \newcommand\;rxya[2]{\;tc#1\;abs\;tc \;tcb#2\;abs\;tcb
372 \ifnum\;tc>\;tcb \;rc\;tcb \;tcb\;tc \;tc\;rc \fi
373 \;rc\;tc \divide\;rc\thr@@ \advance\;rc\;tcb

374 }

375

Replaces argument by magnitude

376 \newcommand\;abs[1]{\ifnum#1<\z@ #1-#1\fi}

377

One iteration of square root calculation by Newton’s method.

378 \newcommand\;rroot{\;tcb\;tc \divide\;tcb\;rc
379 \advance\;rc\;tcb \divide\;rc\tw@}

380

11.6 Dash Pattern Drawing

 Variable uses in \;dashes, \;scdashes, \;nscdashes, \;pdashes and \;dash.

counts

\;scp = distance between points. \;rc = length of Bezier segment. \;rtc = total points in Bezier segment. \;np = number of whole patterns in Bezier segment or scratch. \;overhang = of dash pattern past symbol or end of segment. \;pbs = total points between symbols \;pns = points to next symbol or dot. \;tc = number of points to blank for curve symbol. \;tcb = number of points along pattern. dimens \;pl = length of dash pattern. \;ucd = dash pattern unit length. Initializes dash plot for segment and selects symbol count alternative.

381 \newcommand\;dashes{\let\;ticd\;icurvedashes
382 \let\;tucd\;ucd \divide\;rc\;t
383 \;rtc\;t \;tc\;rc \advance\;tc\csdiameter \divide\;tc\;rc
384 \divide\;tc\tw@ \;t\;tc \multiply\;tc\tw@ \;ptfalse \;cnd\;mcnd

385 \;pbs\;rc \divide\;pbs\tw@
386 \advance\;overhang\;pbs \divide\;overhang-\;rc
387 \if;scnt \;scdashes \else \;nscdashes \fi \multiply\;overhang\;rc}

388

Plots dash pattern when a nonzero symbol count is specified.

389 \newcommand\;scdashes{\;pbs\;rtc \divide\;pbs\;sc \;ccss \;scp
390 \if;csym \;pl \multiply\;scp\;np \divide\;scp\;sc \advance\;pbs-\;tc
391 \else \;pbs \multiply\;scp\;rc \fi \;np\;overhang \;overhang\z@
392 \divide\;scp\;pbs \;tcb\z@ \;pns\;t \;dash \;overhang\;np
393 \if;csym\else \advance\;overhang-\;tcb \advance\;rtc-\;tcb
394  \advance\;pbs-\;tc \fi
395 \;pns\;pbs \advance\;pns-\;np \if;csym\else\advance\;pns\;tcb\fi
396 \@whilenum\;rtc>\z@\do{\;pdashes \;ptfalse \;t\;tc \;pns\;t \;dash
397  \;pns\;pbs \;overhang\if;csym\;np\else-\;overhang\fi
398  \advance\;pns-\;overhang}\;overhang-\if;csym\;np\else\;overhang
399  \;ptfalse \;t\;tc \;tcb\;overhang
400  \divide\;t\tw@ \;rtc\;t \;pns\;t \;dash \fi}

401

Plots symbols at natural pattern length but shrinks pattern to fit between.

402 \newcommand\;nscdashes{\advance\;pbs\;pl \divide\;pbs\;rc
403 \if;csym \;bpdashes \fi \;ccss \;pns\;t
404 \;dash \advance\;pbs-\;tc \;scp\;pl \divide\;scp\;pbs \;pns\;pbs
405 \@whilenum\;rtc>\z@\do{\;pdashes \;ptfalse \;t\;tc \;pns\;t \;dash
406  \;pns\;pbs}%
407 \if;csym \else \divide\;tc\tw@ \advance\;overhang\;tc \fi}

408

If large symbol spaces, blank curve.

409 \newcommand\;ccss{\ifnum\;pbs>\;tc\else \;bpdashes \fi}

410

A blank or symbol plotting dash pattern

411 \newcommand\;bpdashes{\let\;tucd\;pl \let\;ticd\;ricd \;tc\z@ \;t\z@}
412 \newcommand\;ricd{1,0}

413

Reads dash pattern plotting dashes and spaces up to next symbol space.

414 \newcommand\;pdashes{\ifnum\;pns>\z@ \;td\z@ \;tcb\z@ \;ptfalse
415  \@for\;ci:=\;ticd \do{\advance\;td\;ci\;tucd \;t\;scp \divide\;t\tw@
416  \advance\;t\;td \divide\;t\;scp  \advance\;t-\;tcb \;dash
417  \if;pt\;ptfalse\else\;pttrue\fi}%
418 \let\n;xt\;pdashes \else \let\n;xt\relax \fi \n;xt}

419

Checks if dash or space occurs before or after curve, calculates fractions.

420 \newcommand\;dash{\ifnum\;t=\z@
421  \if;csym \ifnum\;rtc>\z@ \if;pt\;point\;startline\fi \fi \fi
422 \else \advance\;tcb\;t \advance\;pns-\;t
423  \ifnum\;overhang<\z@ \advance\;overhang\;t
424  \;t \ifnum\;overhang<\z@ \z@ \else \;overhang \;overhang\;tcb \fi
425  \else \;overhang\;tcb \fi
426  \ifnum\;pns<\z@ \advance\;overhang\;pns \advance\;tcb\;pns
427  \advance\;t\;pns \;pns\z@ \fi \advance\;rtc-\;t
428  \ifnum\;rtc<\z@ \advance\;overhang\;rtc \advance\;t\;rtc\fi

429  \ifnum\;t>\z@ \if;pt\;point\;startline\fi
430  \let\n;xt\;points \;points \fi\fi}

431

Plots a single dash or space depending on \if;pt.

432 \newcommand\;points{\ifnum\;t<\;cnd \;tca\;t \else \;tca\;cnd \fi
433 \advance\;y\;tca\;dy \;ytd\;tca\;dx \advance\;x\;ytd \kern\;ytd
434 \if;pt\;point\;stopline\fi
435 \ifnum\;t<\;cnd \let\n;xt\relax \advance\;cnd-\;t
436 \else
437  \advance\;t-\;cnd \advance\;dx\;ddx \advance\;dy\;ddy \;cnd\;mcnd
438 \fi \n;xt}

439

Make ‘;’ a punctuation mark again.

440 \catcode`\;=12

441

442 ⟨/package⟩

 12 curvesls.sty

This package file is a L^{A}TEX 2ε compatible replacement for curvesls.sty from versions 1.42 and earlier. It may one day be removed.

443 ⟨∗ls⟩

444 \ProvidesPackage{curvesls}
445 [2000/08/22 Obsolete! Using option emtex in package curves.]
446 \RequirePackage[emtex]{curves}

447 ⟨/ls⟩