%%HP: T(3)A(R)F(.);
@ AIRFOIL, by Matt Nelson
DIR
AIRFOIL
\<<
  "Airfoil?"               @ prompt for airfoil name
  {1}
  INPUT
  OBJ\->              @ get the data array on the stack
  DUP IF TYPE 4 \=/ THEN   @ check to see if this is a complex
    "Not airfoil data"          @ array; assumes any complex array
    DOERR             @ in this directory IS airfoil data
    DROP
    KILL              @ if not, kill the program
  END
  43 MENU             @ select UNITS LENG menu
  "Chord?"            @ prompt for desired chord
  {1}
  INPUT
  OBJ\->              @ put chord on stack
  0 MENU              @ return to previous menu
  CLLCD
  "   working..." 3 DISP   @ display info message
  DUP                 @ get type of argument
  IF TYPE 13 == THEN       @ it is a unit object
    '1_cm' CONVERT         @ assume unit is length, so convert to cm
    OBJ\-> DROP            @ get rid of its unit
  END
  PPAR                @ get current PPAR so we can save it
  \-> chord ppar      @ save desired chord, in cm, and PPAR
  \<<
    # 64d             @ eventual width of PICT we will want
    chord ycmps /          @ required height of PICT, in screens
    CEIL              @ required height of PICT, in integer screens
    \-> nscreen            @ we will need number of screens later
    \<<  {
      (-1.82,0) (1.82,2.11)     @ put a PPAR on stack, so that we have
      X 0 (0,0) FUNCTION Y }    @ something to work with...
      1                    @ PUT index for pmin
      xcmps 2 / NEG        @ get xmin from the real width of output
      0 R\->C PUT          @ put (xmin,0) into our PPAR
      2                    @ PUT index for below...
      xcmps 2 /            @ get xmax from the real width of output
      nscreen ycmps *      @ new ymax = #screens * (cm/screen)
      R\->C PUT            @ make it complex, and shove it into PPAR
      'PPAR' STO      @ store it for use
      nscreen 64 * R\->B PDIM   @ make PICT the appropriate size
@
@ at this point, we still have the array of coordinates on the stack,
@ so re-scale them into cm
@
      DUP SIZE OBJ\-> DROP @ get size of array
      -100 100 -100 100         @ initialize xmax=ymax=-100, xmin=ymin=100
      \-> size xmax xmin ymax ymin
      \<<
        1 1 size
        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 size 1 -
        START DUP NEXT          @ make two arrays of 1's, size of data
        size 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, now has [0,1] x-range
        chord *            @ multiply by chord for proper scale
@
@ we now have a properly scaled array of coordinates on the stack, so
@ connect the dots between adjacent points
@
        ERASE              @ clear PICT
        1 size 1 -         @ need one less than size of the array
        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
          LINE             @ draw a line between the two points
        NEXT
        DROP               @ don't need the array of points anymore
      \>>
@
@ now PICT has the airfoil drawn on it, so display it screen
@ by screen, dumping it to the printer
@
      CR              @ put print head over to right
      1 nscreen            @ there will be nscreen dumps
      FOR i
        # 0d               @ upper left hand x-pixel coordinate to display
        i 1 - 64 * R\->B   @ upper right hand y-pixel coordinate "
        2 \->LIST          @ put pixel coordinates in a list
        PVIEW              @ and display PICT
        PRLCD              @ send display to printer
      NEXT
    \>>
@
@ we is done, so clean up
@
    ppar DUP
    IF TYPE 6 == THEN      @ there was no PPAR, and we just saved a name
      DROP            @ at top of program; just drop it
      'PPAR' PURGE         @ and get rid of the one we created
    ELSE
      'PPAR' STO      @ there was a PPAR, so restore it
    END
    PICT PURGE             @ get back the memory used by PICT
  \>>
\>>


ycmps                 @ height of one screen of PRINTED OUTPUT, cm
  2.096

xcmps                 @ width of one screen of PRINTED OUTPUT, cm
  3.60

SD7003                @ sample airfoil, the Selig-Donovan 7003
  [ (1.00000,0.0)
    (0.99681,0.00031)
    (0.98745,0.00132)
    (0.97235,0.00310)
    (0.95193,0.00547)
    (0.92639,0.00824)
    (0.89600,0.01139)
    (0.86112,0.01494)
    (0.82224,0.01884)
    (0.77985,0.02304)
    (0.73449,0.02744)
    (0.68673,0.03197)
    (0.63717,0.03649)
    (0.58641,0.04086)
    (0.53499,0.04494)
    (0.48350,0.04859)
    (0.43249,0.05171)
    (0.38250,0.05415)
    (0.33405,0.05581)
    (0.28760,0.05658)
    (0.24358,0.05639)
    (0.20240,0.05518)
    (0.16442,0.05292)
    (0.12993,0.04961)
    (0.09921,0.04526)
    (0.07244,0.03993)
    (0.04978,0.03372)
    (0.03130,0.02677)
    (0.01702,0.01932)
    (0.00697,0.01172)
    (0.00127,0.00438)
    (0.00025,-0.00186)
    (0.00457,-0.00741)
    (0.01408,-0.01285)
    (0.02839,-0.01759)
    (0.04763,-0.02141)
    (0.07182,-0.02438)
    (0.10073,-0.02660)
    (0.13407,-0.02809)
    (0.17150,-0.02888)
    (0.21268,-0.02900)
    (0.25719,-0.02852)
    (0.30456,-0.02752)
    (0.35426,-0.02608)
    (0.40572,-0.02428)
    (0.45837,-0.02217)
    (0.51161,-0.01980)
    (0.56484,-0.01723)
    (0.61748,-0.01450)
    (0.66898,-0.01167)
    (0.71883,-0.00887)
    (0.76644,-0.00628)
    (0.81118,-0.00403)
    (0.85241,-0.00220)
    (0.88957,-0.00082)
    (0.92210,0.00008)
    (0.94952,0.00052)
    (0.97134,0.00057)
    (0.98718,0.00037)
    (0.99679,0.00011)
    (1.00001,-0.00000) ]

END
