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 --------------------------------------------------------------------------