nelson@ (Matt Nelson) (10/30/90)
This is for all of the R/C model airplane/sailplane enthusiasts out there, especially if you are into designing and building. If you have no interest in model aircraft, you might as well hit 'n' now. Here is the latest version of my airfoil section plotter. I needed to plot some ribs for a glider project, and realized that I had sold my trusty HP-28s. I quickly re-wrote my original program to run on the HP-48sx, and came up with something MUCH prettier, and MUCH MUCH faster. This thing is really quite painless to use now (the 28s version was slooooow). The speedup came from creating a PICT that is big enough to contain the entire airfoil section. The airfoil data is plotted only once, and then sent to the printer, one screen at a time, through successive PVIEW and PRLCD commands. BE WARNED... although this is a very fast way to print out large objects, it is also a memory-hungry way to do it. for example, a 10" SD7003 required a PICT that was 131 by 832. When I saved this PICT to the stack and BYTESed it, it was 14,154 bytes big. On top of that, just the data for the SD7003 (as listed below) is 988.5 bytes long. All I am saying is that this program DOES use a lot of memory, but is very handy, and serves my purposes very well; if you don't like it, feel free to use something else. To use this program, simply download the listing below, get into the new directory, and hit [AIRFOI]. It will ask for an airfoil. Just hit the menu button corresponding to the airfoil data you wish to use (you can hit [SD700] to try it out), then [ENTER]. It will then ask for a chord. Give it a number corresponding to the desired chord, in centimeters, then [ENTER]. The program will handle other units, and in fact presents you with the UNITS LENG menu, so you can give it a chord size in any unit you wish. Just be sure to give it a valid unit object (you have to supply the underscore manually, since the calculator is in program entry mode at this point). You should be greeted by a "working..." message. Point the calculator at your 82240A/B printer, and watch the airfoil section print out. The airfoil data is assumed to be in a complex vector, where each element corresponds to a point (x,y) on the airfoil. The points should be arranged so that if you were to draw lines sequentially from one point to the next, you would trace out a closed outline of the airfoil section. The sample airfoil in this posting, the SD7003, should help illustrate this. For those who are interested, the SD7003 is an airfoil designed specifically for use at very low Reynolds numbers, such as those encountered by model sailplanes. There are two parameters which control the absolute size of the printed output. These are the global variables ycmps and xcmps. These represent the number of centimeters per screen OF PRINTED OUTPUT for the y and x directions, respectfully. One arrives at these values by printing a screenfull of anything, and measuring the size of the printed output in centimeters. The numbers supplied below are for the 82240A printer; I have never used a 'B' version of the printer, and don't know whether these numbers will have to be changed in order to work properly with that printer. The only reason I left these numbers as global variables is so that the user could have some control over the aspect ratio of the output, without diving into the program itself. Please direct any comments/suggestions/questions etc. to: Matt Nelson internet: nelson@psroot.ps.uci.edu Physics Dept. bitnet: mnelson@uci University of California phone: (714) 725-2629 Irvine, CA 92717 ---snip----snip----snip----snip----snip----snip----snip----snip----snip----snip %%HP: T(3)A(R)F(.); 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