[comp.sys.handhelds] Airfoil plotter

mnelson@vmsa.oac.uci.edu (11/22/89)

      Are there any R/C glider enthusiasts out there?

      The following is a set of routines for printing out model aircraft
airfoils on the HP IR printer.  One simply puts an array of coordinates
(the user must supply the coordinate points for the desired airfoil) and
the desired chord (in inches) on the stack, and a full size airfoil will
slowly emerge from the printer.  The process usually requires >10 screen
dumps, so it may take a while.

      The system consists of 5 programs:  AIRFOIL, SCALE01, DRAWFOIL, XNPLOT,
and LINE.
      It also needs 3 global constants:  AR, SCRIN, PPAR.

Note on listings:
      1) Checksums were calculated with CHECK/ACHK, the m-code version 
         of CHK (they give the same number).
      2) The inequality test symbol is denoted as <> 

The first routine figures out how many screens are required in order to
get the proper chord, then puts a program and an integer on the stack,
which are used by the next program in the chain.

AIRFOIL [5098]

<< SCRIN / DUP                    how many screens are required?
   CEIL                             use next largest integer
   DUP 3 ROLLLD /                   and get a shortening factor
   SWAP ROT ROT *                   multiply coordinates by that factor
   C->R 3 PICK *                  multiply width of foil by number of screens
   AR *                           multiply width by aspect ratio of printer
   R->C SWAP                      re-pack the coords, and set up the stack
   << DRAWFOIL >>                 put a short program on the stack
   SWAP XNPLOT                    go on to next program
   DROP                           when done, get rid of the modified array
>>

The next program is an adaptation of X4PLOT from William Wickes' "HP-28
Insights" (an extremely handy book).  It basically stretches out a plot 
by subdividing the vertical range in the current PPAR.  Wickes' version 
gives 4x elongation, my modification gives arbitrary elongation.  See his 
book for comments on how it works; my extension is relatively self-
explanitory.

XNPLOT [7147]

<< -> n
   << IF PPAR TYPE 6 == THEN
        1 *H 
      END
      PPAR DUP LIST-> 4 DROPN - IM 32 n * 
      1 - / -32 * 0 SWAP R->C 
      -> proc ppar dy
      << CR 'PPAR' 1 OVER EVAL 1 GET 
         dy n 1 - * + 
         PUT
         CLLCD proc EVAL PRLCD
         1 n
         START
           PPAR LIST-> 
           6 ROLL dy - 
           6 ROLL dy -
           6 ROLLD 6 ROLLD ->LIST 
           'PPAR' STO 
           CLLCD proc EVAL PRLCD
         NEXT
         ppar 'PPAR' STO
      >>
   >>
>>

The following does the actual drawing of the airfoil.

DRAWFOIL [CF87]

<< CLLCD
   DUP SIZE LIST-> DROP           get the number of points in the array
   1 -                            need one less than that...
   -> max
   << 1 max
      FOR i
        DUP i GETI
        4 ROLLD GET ROT           put the first pair of points on the stack
        C->R SWAP R->C              swap x and y so foil comes out long-wise
        SWAP
        C->R SWAP R->C              do same with 2nd point
        PPAR DUP 1 GET            get min screen coord
        SWAP 2 GET                get max screen coord
        C->R SWAP DROP            only keep xmax
        SWAP C->R SWAP DROP       and ymax
        -> p1 p2 xhi xlo
        << p1 C->R SWAP DROP      get the x coord's of the points for
           p2 C->R SWAP DROP        the later tests
           -> x1 x2
           << IF x1 xhi >         is x1 off top of screen?
                 x2 xhi >         is x2 off top of screen?
                 AND              are they both off top of screen?
                 x1 xlo <         is x1 off bottom of screen?
                 x2 xlo <         is x2 off bottom of screen?
                 AND              are they both off bottom of screen?
                 OR               (both points off the top) or ( " bottom)?
                 NOT              if not, then some part of the segment
               THEN                 joining the two is visible, so draw
                 p1 p1 LINE         a line between the two points
               END
           >>
        >>
      NEXT
   >>
>>

The above routines assume that the x-range of the coordinate points for
the airfoil range from 0 to 1.  While this is often times the case, it
is not always true.  The following routine will re-scale all of the 
points in the array so that they are in the range 0 to 1.  Both the x and
y values are scaled, so as to preserve the aspect ratio of the airfoil.
This also shifts the data so that the y-coordinates are centered about 0.

SCALE01 [B295]

<< DUP SIZE LIST-> DROP           get size of array
   -100 100 -100 100              initialize xmax=ymax=-100, xmin=ymin=100
   -> s xmax xmin ymax ymin
   << 1 1 s
      START                       scan the array looking for max & min x
        GETI C->R                 get the x and y coord
        -> x y
        << x xmin MIN             put minimum of x and xmin in xmin
           'xmin' STO
           x xmax MAX             put maximum of x and xmax in xmax
           'xmax' STO
           y ymin MIN             put minimum of y and ymin in ymin
           'ymin' STO
           y ymax MAX             put maximum of y and ymax in ymax
           'ymax' STO
        >>
      NEXT
      DROP                        get rid of the GETI index
      1 1 s 1 -
      START DUP NEXT              make two arrays of 1's, size of data
      s 1 ->LIST ->ARRY DUP
      ROT C->R                    get y-coordinates
      4 ROLL ymax ymin + 2 / *    make array of average y value
      -                           shift y values by subtracting average
      3 ROLLD SWAP xmin * -       subtract xmin from all x values
      SWAP R->C                   re-pack complex array
      xmax xmin - /               scale entire array
   >>
>>

The following routine is reproduced without permission from "HP-28
Insights" by William Wickes.  If you don't own this book, get it.
It contains many handy tips and programs, and was my primary reference
when I was learning how to use the HP-28S.  This routine draws a line
from world coordinate p1 to world coordinate p2 (p1, p2 are complex
numbers).

LINE [170D]

<< OVER PIXEL
   IF DUP2 <>
   THEN OVER -
     PPAR DUP 2 GET SWAP
     1 GET
     - C->R 31 / SWAP
     136 /
     3 PICK C->R
     4 ROLL / ABS
     SWAP ROT / ABS
     MAX
     PPAR 4 GET /
     SWAP OVER /
     ROT
     1 4 ROLL
     START
       OVER + DUP PIXEL
     NEXT
   END
   DROP2
>>

The following constants are needed by the program:

AR
1.2                               Aspect ratio of printed output

SCRIN
0.402667104097                    Number of inches per screen when
                                  screen is dumped to printer

PPAR plays a big role, and the values in it were arrived at by wanting
a display which has a 1-1 aspect ratio and has the y range of 0 to 1.
Note that if the airfoil drawing process is interrupted by an ATTN, the
PPAR corrupted.  It is easy to fix, though, since just the y values of
the min and max coordinates are changed; just set them back to 0 and 1 to
repair it.

PPAR
{ (-2.193548371,0) ( 2.193548371,1)
  X 1 (0,0) }

The array of coordinates for the airfoil should be formatted in such a
way that if you plot successive points in the array, you would trace out
the airfoil.  As an example, take the following array, which represents
a diamond shape which is twice as long as it is wide.

SHAPE
[ (0,0) (.2,.1) (.4,0) (.2,-.1) (0,0) ]

As you can see, first the top of the shape is plotted, then it returns to
the first point as it plots the bottom of the shape.

To see how the system works, lets say that you want a diamond 2 inches long
(that means that it should be 1 inch wide).  You would do the following:

      SHAPE             get the array on the stack
      SCALE01           re-scale it (original did not have x limits [0,1])
      2                 want it two inches long
      AIRFOIL           let 'er rip

Assuming that your printer was turned on and in sight, you should see a
diamond appear.  Check it's size with a ruler... if it is a little off
from 2x1, you can tweek the SCRIN and AR values till it is perfect (it
should be pretty good, though...).  The results are even more exciting
when SHAPE is replaced by a real airfoil.  It is possible to run into
problems if the airfoil is very thick; part of the graph could get cut
off.  If this happens, you're outta luck; the printer ain't big enough
for your application.  The HP printer can handle anything under about 
1.5 inches wide, which is suitable for many glider applications (I don't
have any experience with powered wing sizings).

Now key in your favorite airfoil coordinates, and you are ready to make
rib templates!

Any comments/questions/suggestions/improvements are welcome.

--------------------------------------------------------------------------
Matt Nelson, Physics Dept., U.C. Irvine, Irvine, CA 92717, (714)856-6496
--------------------------------------------------------------------------