[comp.text] How can I draw lines thru terms in eqn?

pstowne@zargon.lerc.nasa.gov (Charlie Towne) (02/21/91)

Using troff and eqn from DWB 2.0, I'd like to be able to draw a slanted 
line through various terms in an equation, to indicate that those terms
are being neglected in an analysis.  The endpoints of each line to be 
drawn should be the lower-left and upper-right corners of a box 
surrounding the relevant term in the equation.  Does anyone have any 
ideas on the best way to do this?

I know about pic, although I've never used it.  Can pic be used inside
eqn delimiters?  If so, how can I mark the endpoints of the line to be 
drawn?

--
Charlie Towne                        Email: pstowne@zargon.lerc.nasa.gov  
MS 5-11                              Phone: (216) 433-5851
NASA Lewis Research Center
Cleveland, OH 44135

pstowne@zargon.lerc.nasa.gov (Charlie Towne) (03/29/91)

A few weeks ago I posted an article asking how to draw slanted lines
through terms in equations in troff, to show which terms were being
neglected in an analysis.  Thanks to ideas supplied by Mark Brader 
(msd@sq.com) and Dan Whipple (pswhip@avelon.lerc.nasa.gov), I've been 
able to do what I wanted.  It's "not perfect", but it works.  This might 
be of interest to someone else, so I'm posting what I came up with.

Actually drawing a slanted line is easy, using \D'l x y' to draw a line
from the current position to the position given by x and y.  The tricky
part is getting to the correct "current position" and defining x and y.

Dan suggested getting the height of the term to be crossed out by
putting it into a diversion and interpolating the dn number register,
storing the result in a separate user-defined number register.  This 
would determine the y-position of the end of the line to be drawn, if 
the starting y-position were known.  That's the "not perfect" part.  
After formatting the equation and before drawing the line, you have to 
move up some appropriate amount, using \v, to be at the correct 
y-position for the beginning of the line to be drawn.

Mark suggested getting the x-positions by using \k escape sequences 
on either side of the term to be crossed out.  \k writes the horizontal
position on the input line into a specified user-defined number register.
E.g., \kX writes into X and \k(XX writes into XX.  These can then be 
referenced using the | notation for absolute positioning.

After doing all this, the line can be drawn using something like the 
following.  This assumes the height of the term has been stored in the 
number register v1, and that the \k's have been used to store the 
x-positions of the end points of the line to be drawn into the number
registers h1 and h2.

   \v'-1v'\h'|\n(h1u'\D'l |\n(h2u -\n(v1u'\v'\n(v1u'\v'1v'

At first glance this looks like something my 2-year-old son would type, 
to me anyway, so I'll explain each term.

1.  \v'-1v' moves up the appropriate amount (in this case, 1 line space) 
    to be at the correct y-position for the beginning of the line 
    to be drawn.

2.  \h'|\n(h1u' moves horizontally to the point h1 device units from 
    the left margin, corresponding to the x-position of the beginning
    of the line to be drawn.

3.  \D'l |\n(h2u -\n(v1u' draws the line, starting at the current point.
    The ending x-position is h2 units from the left margin, and the 
    y-position is v1 units above the starting point.

4.  \v'\n(v1u' moves back down, to the same vertical position as the
    beginning of the line that was drawn.

5.  \v'1v' moves back down to the original vertical position.

BTW, Mark pointed out that the \k's would only give the correct 
positioning for left-justified equations with indent zero.  Paraphrasing
Mark, this is because \k marks the position on the _input_ line.  (And 
only works at all because of the way that eqn constructs equations.  
If someone decided to reimplement eqn, the \k idea could stop working.)
Equations to be indented or centered will have to be put into a 
diversion, then read back with an appropriate indent.  

However, I normally use the mm macros, with each .EQ/.EN pair inside a 
.DS CB/.DE pair.  This worked fine for centered equations.

For anyone _really_ interested in all this, below is a real troff
file that constructs an equation with three terms crossed out.  The
equation is the differential form of the fundamental energy equation
for fluid flow, and the crossed-out terms are those neglected in a
boundary layer analysis.

***** cut here *****
.\" Troff input file for example showing a way to "cross out" terms
.\" in equations.
.\"
.\" This file requires the mm macros and the eqn pre-processor.  To
.\" format it, do:
.\"
.\"    eqn thisfile | troff -mm
.\"
.\" Page margins
.po 1.0i
.ll 6.5i
.\" Define symbols for shear stress and heat flux 
.EQ
define tauxx 'tau sub xx'
define tauxy 'tau sub xy'
define tauyy 'tau sub yy'
define qx    'q sub x'
define qy    'q sub y'
.EN
.\"
.\" Get height of each crossed-out term
.\" 
.di eQ
.EQ
{partial qx} over {partial x}
.EN
.di
.nr v1 \n(dnu     \" Height of 1st term
.di eQ
.EQ
partial over {partial x} ( u tauxx ^+^ v tauxy )
.EN
.di
.nr v2 \n(dnu     \" Height of 2nd term
.di eQ
.EQ
v tauyy
.EN
.di
.nr v3 \n(dnu     \" Height of 3rd term
.\"
.\" Format the equation, bracketing each term to be crossed out
.\" with \k's
.\" 
.DS CB
.EQ
{partial ( rho u H)  } over {partial x} ^+^
{partial ( rho v H)  } over {partial y} ~=~
- 1 over {R e sub r Pr sub r} 
left  ( 
"\k(h1" {partial qx} over {partial x} "\k(h2" ^+^
        {partial qy} over {partial y} ~ 
right ) ^+^ 
1 over {R e sub r} 
left  [ 
"\k(h3" partial over {partial x} ( u tauxx ^+^ v tauxy ) "\k(h4" ^+^
        partial over {partial y} ( u tauxy ^+^ "\k(h5" v tauyy "\k(h6" ) ~ 
right ]
.EN
.\"
.\" Draw the lines
.\"
\v'-1v'\
\h'|\n(h1u'\D'l |\n(h2u -\n(v1u'\v'\n(v1u'\
\h'|\n(h3u'\D'l |\n(h4u -\n(v2u'\v'\n(v2u'\
\v'-0.5v'\
\h'|\n(h5u'\D'l |\n(h6u -\n(v3u'\v'\n(v3u'\
\v'1.5v'
.DE
***** and cut here *****
--
Charlie Towne                        Email: pstowne@zargon.lerc.nasa.gov  
MS 5-11                              Phone: (216) 433-5851
NASA Lewis Research Center
Cleveland, OH 44135