Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator) (01/15/90)
Submitted-by: Anthony M. Richardson <amr@dukee.egr.duke.edu> Posting-number: Volume 90, Issue 009 Archive-name: applications/plplot-2.6/part08 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 8 (of 12)." # Contents: Amiga/plmenu.c docs/chapter3.tex # Wrapped by tadguy@xanth on Sun Jan 14 18:11:55 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Amiga/plmenu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Amiga/plmenu.c'\" else echo shar: Extracting \"'Amiga/plmenu.c'\" \(16175 characters\) sed "s/^X//" >'Amiga/plmenu.c' <<'END_OF_FILE' X#include "plplot.h" X#include "plamiga.h" X#include <math.h> X Xvoid eventwait() X{ X for(;;) { X /* Wait for message */ X Wait(1<<PLWindow->UserPort->mp_SigBit); X if(procmess()) X return; X } X} X XPLINT procmess() X{ X ULONG class; X USHORT code; X struct IntuiMessage *message; X X while(message = (struct IntuiMessage *)GetMsg(PLWindow->UserPort)) { X class = message->Class; X code = message->Code; X ReplyMsg((struct Message *)message); X if(eventhandler(class,code)) X return((PLINT)1); X } X return((PLINT)0); X} X XPLINT eventhandler(class, code) XULONG class; XUSHORT code; X{ X switch (class) { X case CLOSEWINDOW: X return((PLINT)1); X case MENUPICK: X menuselect(class,code); X break; X case SIZEVERIFY: X break; X case NEWSIZE: X if(!(PLCurPrefs.WinType & PLCUST)) { X PLCurPrefs.WWidth = PLWindow->Width; X PLCurPrefs.WHeight = PLWindow->Height; X } X else { X PLCurPrefs.CWidth = PLWindow->Width; X PLCurPrefs.CHeight = PLWindow->Height; X } X setlimits(); X disablegads(0); X disablemenus(); X remakeplot(); X enablemenus(); X enablegads(); X break; X default: X break; X } X X return((PLINT)0); X} X Xstruct IntuiText IText0ItemScrSubs[] = { X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"WorkBench", NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Custom", NULL} X}; X Xstruct MenuItem Menu0ItemScrSubs[] = { X { X &Menu0ItemScrSubs[1], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X 0xFFFE, X (APTR)&IText0ItemScrSubs[0], X NULL, X NULL, X NULL, X NULL X }, X { X NULL, X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X 0xFFFD, X (APTR)&IText0ItemScrSubs[1], X NULL, X NULL, X NULL, X NULL X } X}; X Xstruct IntuiText IText0ItemPriSubs[] = { X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Bitmap Dump", NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Full Page (Landscape)", NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Full Page (Portrait)", NULL} X}; X Xstruct MenuItem Menu0ItemPriSubs[] = { X { X &Menu0ItemPriSubs[1], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X NULL, X (APTR)&IText0ItemPriSubs[0], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu0ItemPriSubs[2], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X NULL, X (APTR)&IText0ItemPriSubs[1], X NULL, X NULL, X NULL, X NULL X }, X { X NULL, X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X NULL, X (APTR)&IText0ItemPriSubs[2], X NULL, X NULL, X NULL, X NULL X } X}; X Xstruct IntuiText IText0[] = { X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Save Configuration",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Reset",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Maintain Plot Aspect",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Redraw Enabled",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Select Screen Type",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Print",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Save Bitmap as IFF file",NULL} X}; X Xstruct MenuItem Menu0Items[] = { X { X &Menu0Items[1], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X 0, X (APTR)&IText0[0], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu0Items[2], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X 0, X (APTR)&IText0[1], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu0Items[3], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, X 0, X (APTR)&IText0[2], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu0Items[4], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, X 0, X (APTR)&IText0[3], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu0Items[5], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X 0, X (APTR)&IText0[4], X NULL, X NULL, X &Menu0ItemScrSubs[0], X NULL X }, X { X &Menu0Items[6], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X 0, X (APTR)&IText0[5], X NULL, X NULL, X &Menu0ItemPriSubs[0], X NULL X }, X { X NULL, X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X 0, X (APTR)&IText0[6], X NULL, X NULL, X NULL, X NULL X } X}; X Xstruct IntuiText IText1Item2Subs[] = { X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)" 2", NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)" 4", NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)" 8", NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"16", NULL} X}; X Xstruct MenuItem Menu1Item2Subs[] = { X { X &Menu1Item2Subs[1], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X 0xFFFE, X (APTR)&IText1Item2Subs[0], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu1Item2Subs[2], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X 0xFFFD, X (APTR)&IText1Item2Subs[1], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu1Item2Subs[3], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X 0xFFFB, X (APTR)&IText1Item2Subs[2], X NULL, X NULL, X NULL, X NULL X }, X { X NULL, X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT, X 0xFFF7, X (APTR)&IText1Item2Subs[3], X NULL, X NULL, X NULL, X NULL X } X}; X Xstruct IntuiText IText1[] = { X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Interlaced", NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"High Resolution",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Number of Colors",NULL}, X {0, 1, JAM1, 0, 0, NULL, (UBYTE *)"Set Color Palette",NULL} X}; X X Xstruct MenuItem Menu1Items[] = { X { X &Menu1Items[1], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, X 0, X (APTR)&IText1[0], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu1Items[2], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT | MENUTOGGLE, X 0, X (APTR)&IText1[1], X NULL, X NULL, X NULL, X NULL X }, X { X &Menu1Items[3], X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X 0, X (APTR)&IText1[2], X NULL, X NULL, X &Menu1Item2Subs[0], X NULL X }, X { X NULL, X 0, 0, 0, 0, X ITEMTEXT | ITEMENABLED | HIGHCOMP, X 0, X (APTR)&IText1[3], X NULL, X NULL, X NULL, X NULL X } X}; X Xstruct Menu Menu[] = { X { X &Menu[1], X 0, 0, 0, 0, X MENUENABLED, X "PLPlot", X &Menu0Items[0] X }, X { X NULL, X 0, 0, 0, 0, X MENUENABLED, X "Screen Format", X &Menu1Items[0] X } X}; X Xenum menus { PLMCONTROL, PLMSCREEN }; X X/* Control menu items */ Xenum menu0items { PLMSAVECONFIG, PLMRECONFIG, PLMASPECT, PLMBUFF, X PLMSCREENTYPE, PLMSCRDUMP, PLMSIFF }; Xenum menu0itemscrsubs { PLMWBENCH, PLMCUSTOM }; Xenum menu0itemprisubs { PLMPRWIN, PLMPRPLAN, PLMPRPPOR }; X X/* Custom screen menu items */ Xenum menu1items { PLMLACE, PLMHIRES, PLMCOLORS, PLMCOLREQ }; X/* Number color subitems */ Xenum menu1item2subs {PLMC2, PLMC4, PLMC8, PLMC16 }; X Xvoid MakePLMenu() X{ X short mtx, mledge; X short itx, itxlen, itedge, ichk; X short stx, stxlen, stedge, schk; X short fheight; X char *string; X struct Menu *menu; X struct MenuItem *item, *subitem; X struct IntuiText *itext; X X fheight = PLScreen->Font->ta_YSize; X X if(PLCurPrefs.WinType & PLCUST) X Menu[0].NextMenu = &Menu[1]; X else X Menu[0].NextMenu = NULL; X X mledge = 0; X for(menu=Menu; menu!=NULL; menu=menu->NextMenu) { X string = (char *)menu->MenuName; X mtx = (short)TextLength(PLSRPort,string,(long)strlen(string)); X /* Leave two character space between menus */ X mtx += (2*mtx)/strlen(string); X menu->LeftEdge = mledge; X menu->Width = mtx; X mledge += mtx; X X /* Find length of longest menuitem in this menu */ X itxlen = 0; X ichk = 0; X for(item=menu->FirstItem; item!=NULL; item=item->NextItem) { X itext = (struct IntuiText *)item->ItemFill; X string = (char *)itext->IText; X itx = (short)TextLength(PLSRPort,string,(long)strlen(string)); X itxlen = max(itxlen,itx); X if(item->Flags & CHECKIT) X ichk = 1; X } X itedge = 0; X for(item=menu->FirstItem; item!=NULL; item=item->NextItem) { X item->Width = itxlen; X item->LeftEdge = 0; X item->TopEdge = itedge; X item->Height = fheight; X if(ichk) { X item->Width += CHECKWIDTH; X itext = (struct IntuiTest *)item->ItemFill; X itext->LeftEdge = CHECKWIDTH; X } X itedge += fheight; X stxlen = 0; X schk = 0; X for(subitem=item->SubItem;subitem!=NULL;subitem=subitem->NextItem){ X itext = (struct IntuiText *)subitem->ItemFill; X string = (char *)itext->IText; X stx = (short)TextLength(PLSRPort,string,(long)strlen(string)); X stxlen = max(stxlen,stx); X if(subitem->Flags & CHECKIT) X schk = 1; X } X stedge = 0; X for(subitem=item->SubItem;subitem!=NULL;subitem=subitem->NextItem){ X subitem->Width = stxlen; X subitem->LeftEdge = item->Width/2; X subitem->TopEdge = stedge; X subitem->Height = fheight; X if(schk) { X subitem->Width += CHECKWIDTH; X itext = (struct IntuiTest *)subitem->ItemFill; X itext->LeftEdge = CHECKWIDTH; X } X stedge += fheight; X } X } X } X X if(PLCurPrefs.WinType & PLCUST) { X Menu0ItemScrSubs[PLMCUSTOM].Flags |= CHECKED; X Menu0ItemScrSubs[PLMWBENCH].Flags &= ~CHECKED; X Menu1Items[PLMLACE].Flags |= ITEMENABLED; X Menu1Items[PLMHIRES].Flags |= ITEMENABLED; X Menu1Items[PLMCOLORS].Flags |= ITEMENABLED; X } X else { X Menu0ItemScrSubs[PLMCUSTOM].Flags &= ~CHECKED; X Menu0ItemScrSubs[PLMWBENCH].Flags |= CHECKED; X } X X Menu1Item2Subs[PLMC2].Flags &= ~CHECKED; X Menu1Item2Subs[PLMC4].Flags &= ~CHECKED; X Menu1Item2Subs[PLMC8].Flags &= ~CHECKED; X Menu1Item2Subs[PLMC16].Flags &= ~CHECKED; X Menu1Item2Subs[PLCurPrefs.Depth-1].Flags |= CHECKED; X X if(PLCurPrefs.ScrType & PLLACE) X Menu1Items[PLMLACE].Flags |= CHECKED; X else X Menu1Items[PLMLACE].Flags &= ~CHECKED; X X if(PLCurPrefs.ScrType & PLHIRES) X Menu1Items[PLMHIRES].Flags |= CHECKED; X else X Menu1Items[PLMHIRES].Flags &= ~CHECKED; X X if(PLCurPrefs.WinType & PLASP) X Menu0Items[PLMASPECT].Flags |= CHECKED; X else X Menu0Items[PLMASPECT].Flags &= ~CHECKED; X X if(PLCurPrefs.WinType & PLBUFF) X Menu0Items[PLMBUFF].Flags |= CHECKED; X else X Menu0Items[PLMBUFF].Flags &= ~CHECKED; X X SetMenuStrip(PLWindow,Menu); X} X Xvoid disablemenus() X{ X OffMenu(PLWindow, PLMCONTROL | SHIFTITEM(NOITEM)); X OffMenu(PLWindow, PLMSCREEN | SHIFTITEM(NOITEM)); X} X Xvoid enablemenus() X{ X OnMenu(PLWindow, PLMCONTROL | SHIFTITEM(NOITEM)); X OnMenu(PLWindow, PLMSCREEN | SHIFTITEM(NOITEM)); X} X Xvoid menuselect(class, code) XULONG class; XUSHORT code; X{ X PLINT ItemNumber, MenuNumber, SubNumber; X PLINT remake=0; X struct MenuItem *Item; X X if(class == VANILLAKEY) X ; X else if(class == MENUPICK) { X while(code != MENUNULL) { X Item = ItemAddress(Menu,code); X MenuNumber = MENUNUM(code); X ItemNumber = ITEMNUM(code); X SubNumber = SUBNUM(code); X if(MenuNumber == PLMCONTROL) { X if(ItemNumber == PLMSAVECONFIG) { X if(!(PLCurPrefs.WinType & PLCUST)) { X PLCurPrefs.WXPos = PLWindow->LeftEdge; X PLCurPrefs.WYPos = PLWindow->TopEdge; X } X else { X PLCurPrefs.CXPos = PLWindow->LeftEdge; X PLCurPrefs.CYPos = PLWindow->TopEdge; X } X SetPLDefs(); X } X else if(ItemNumber == PLMRECONFIG) { X RestorePrefs(); X remake = 1; X } X else if(ItemNumber == PLMASPECT) { X if(Item->Flags & CHECKED) { X PLCurPrefs.WinType |= PLASP; X } X else { X PLCurPrefs.WinType &= ~PLASP; X } X setlimits(); X disablegads(0); X disablemenus(); X remakeplot(); X enablemenus(); X enablegads(); X } X else if(ItemNumber == PLMBUFF) { X if(Item->Flags & CHECKED) { X PLCurPrefs.WinType |= PLBUFF; X } X else { X PLCurPrefs.WinType &= ~PLBUFF; X } X } X else if(ItemNumber == PLMSCREENTYPE) { X if(SubNumber == PLMWBENCH) { X if(!(PLCurPrefs.WinType & PLCUST)) goto reselect; X PLCurPrefs.CXPos = PLWindow->LeftEdge; X PLCurPrefs.CYPos = PLWindow->TopEdge; X PLCurPrefs.WinType &= ~PLCUST; X } X else if(SubNumber == PLMCUSTOM) { X if(PLCurPrefs.WinType & PLCUST) goto reselect; X /* Save wbench window position */ X PLCurPrefs.WXPos = PLWindow->LeftEdge; X PLCurPrefs.WYPos = PLWindow->TopEdge; X PLCurPrefs.WinType |= PLCUST; X } X remake = 1; X } X else if(ItemNumber == PLMSCRDUMP) { X /* Disable system gadgets */ X disablegads(SubNumber); X disablemenus(); X screendump(SubNumber); X enablemenus(); X enablegads(); X } X else if(ItemNumber == PLMSIFF) { X disablegads(0); X disablemenus(); X saveiff(); X enablemenus(); X enablegads(); X } X } X else if(MenuNumber == PLMSCREEN) { X if(ItemNumber == PLMLACE) { X if(Item->Flags & CHECKED) X PLCurPrefs.ScrType |= PLLACE; X else X PLCurPrefs.ScrType &= ~PLLACE; X PLCurPrefs.CWidth = 0; X PLCurPrefs.CHeight = 0; X remake = 1; X } X else if(ItemNumber == PLMHIRES) { X if(Item->Flags & CHECKED) X PLCurPrefs.ScrType |= PLHIRES; X else X PLCurPrefs.ScrType &= ~PLHIRES; X PLCurPrefs.CWidth = 0; X PLCurPrefs.CHeight = 0; X remake = 1; X } X else if(ItemNumber == PLMCOLORS) { X if(SubNumber == PLMC2) { X if(PLCurPrefs.Depth == 1) goto reselect; X PLCurPrefs.Depth = 1; X } X else if(SubNumber == PLMC4) { X if(PLCurPrefs.Depth == 2) goto reselect; X PLCurPrefs.Depth = 2; X } X else if(SubNumber == PLMC8) { X if(PLCurPrefs.Depth == 3) goto reselect; X PLCurPrefs.Depth = 3; X } X else if(SubNumber == PLMC16) { X if(PLCurPrefs.Depth == 4) goto reselect; X PLCurPrefs.Depth = 4; X } X PLCurPrefs.CXPos = PLWindow->LeftEdge; X PLCurPrefs.CYPos = PLWindow->TopEdge; X remake = 1; X } X else if(ItemNumber == PLMCOLREQ) { X disablegads(1); X disablemenus(); X plcolreq(); X enablemenus(); X enablegads(); X } X } Xreselect: X code = Item->NextSelect; X } X } X if(remake) { X ClosePLWind(); X OpenPLWind(); X setlimits(); X disablegads(0); X disablemenus(); X remakeplot(); X enablemenus(); X enablegads(); X } X} X END_OF_FILE if test 16175 -ne `wc -c <'Amiga/plmenu.c'`; then echo shar: \"'Amiga/plmenu.c'\" unpacked with wrong size! fi # end of 'Amiga/plmenu.c' fi if test -f 'docs/chapter3.tex' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'docs/chapter3.tex'\" else echo shar: Extracting \"'docs/chapter3.tex'\" \(24805 characters\) sed "s/^X//" >'docs/chapter3.tex' <<'END_OF_FILE' X\chapter {Advanced Use of PLPLOT}\label{advanced} X XIn this chapter, we describe more precisely how to control the position Xand scaling of a graph, how to alter the low-level line and character Xattributes, and how to use the functions in PLPLOT for drawing Xthree-dimensional surface plots and contour plots. X X\section {Basic PLPLOT Concepts} X XWhen drawing a graph, the programmer usually wishes to specify the Xcoordinates of the points to be plotted in terms of the values of the Xvariables involved. These coordinates are called {\em world Xcoordinates}, and may have any floating-point value representable by the Xcomputer. The {\em window} refers to the rectangular region of Xworld-coordinate space which is to be graphed. This window is mapped Xonto a rectangular region of the {\em view surface}, which is (a Xportion) of the screen or sheet of paper in the output device. This Xphysical region onto which the window is mapped is called the {\em Xviewport}. Before a graph can be drawn, the program must define both the Xwindow and the viewport by calling appropriate routines in PLPLOT. X X\section {Specifying the View Surface} X XThe first thing that a graphics program must do is to tell PLPLOT which Xdevice it is going to use, and how this device is to be divided up for Xgraph plotting. There are two routines that do this, \rou{plstar}, which Xprompts at the console for the output device type and \rou{plbeg}, which Xexpects to be supplied the code number of the device as an argument. The Xcode numbers required by {\tt plbeg} are the same as displayed by {\tt Xplstar} when it prompts for a device. X XBesides selecting the device, {\tt plstar} and {\tt plbeg} allow the Xuser to divide the output device plotting area into several subpages of Xequal size, each of which can be used separately. The routine {\tt Xpladv} is used to advance to a particular subpage or to the next Xsubpage. The screen is cleared or a new piece of paper is loaded, if a Xnew subpage is requested when there are no subpages left on the current Xpage. When a page is divided into subpages, the default character, Xsymbol and tick sizes are scaled inversely as the square root of the Xnumber of subpages in the vertical direction. X XAt the end of a plotting program, it is important to close the plotting Xdevice by calling \rou{plend}. This flushes any Xinternal buffers and frees any memory that may have been allocated. XNote that if {\tt plstar} Xor {\tt plbeg} is called more than once during a program to Xchange the output device, an automatic call to {\tt plend} is made Xbefore the new device is opened. X X\section {Defining the Viewport} \label{viewport} X XAfter defining the view surface, it is necessary to define the portion Xof this surface which is to be used for plotting the graph. All lines Xand symbols (except for labels drawn by {\tt plbox}, {\tt plmtex} and X{\tt pllab}) are clipped at the viewport boundaries. X XViewports are created within the current subpage. If the division of the Xoutput device into equally sized subpages is inappropriate, it is best Xto specify only a single subpage which occupies the entire output device X(by setting {\tt nx=1} and {\tt ny=1} in {\tt plbeg} or {\tt plstar}), Xand use one of the viewport specification subroutines below to place the Xplot in the desired position on the page. X XThere are two methods for specifying the viewport size, using the Xsubroutines \rou{plvpor} and \rou{plsvpa}. Each of these has the format: X\begin{verbatim} Xplvpor(xmin,xmax,ymin,ymax); Xplsvpa(xmin,xmax,ymin,ymax); X\end{verbatim} Xwhere in the case of {\tt plvpor}, the arguments are given in {\em Xnormalized subpage coordinates} which are defined to run from 0.0 to 1.0 Xalong each edge of the subpage. Thus for example, X\begin{verbatim} Xplvpor(0.0,0.5,0.5,1.0); X\end{verbatim} Xuses the top left quarter of the current subpage. X XIn order to get a graph of known physical size, the routine {\tt plsvpa} Xdefines the viewport in terms of absolute Xcoordinates (millimetres) measured from the bottom left-hand corner of Xthe current subpage. This routine should only be used when the size of Xthe view surface is known, and a definite scaling is required. X XTo help the user call {\tt plsvpa} correctly, the routine \rou{plgspa} Xis provided which returns the positions of the extremities of the Xcurrent subpage measured in millimetres from the bottom left-hand corner Xof the device. Thus, if to set up a viewport with a 10.0~mm margin Xaround it within the current subpage, the following sequence of calls Xmay be used X\begin{verbatim} Xplgspa(xmin,xmax,ymin,ymax); Xplsvpa(10.0,xmax-xmin-10.0,10.0,ymax-ymin-10.0); X\end{verbatim} XA further routine \rou{plvsta} is available which sets up a standard Xviewport within the current subpage with suitable margins on each side Xof the viewport. This may be used for simple graphs, as it leaves enough Xroom for axis labels and a title. This standard viewport is that used by X{\tt plenv} (see Section \ref{plenv-sec}). X X\section {Defining the Window} \label{window} X XThe window must be defined after the viewport in order to map the world Xcoordinate rectangle into the viewport rectangle. The routine X\rou{plwind} is used to specify the rectangle in world-coordinate space. XFor example, if we wish to plot a graph showing the collector current X$I_C$ as a function of the collector to emitter voltage $V_{CE}$ for a Xtransistor where $0\le I_C\le 10.0\mbox{\,mA}$ and $0\le V_{CE}\le X12.0\mbox{\,V}$, we would call the function {\tt plwind} as follows: X\begin{verbatim} Xplwind(0.0,12.0,0.0,10.0); X\end{verbatim} XNote that each of the arguments is a floating point number, and so the Xdecimal points are required. If the order of either the X~limits or XY~limits is reversed, the corresponding axis will point in the opposite Xsense, (i.e., right to left for X and top to bottom for Y). The window Xmust be defined before any calls to the routines which actually draw the Xdata points. Note however that {\tt plwind} may also be called to change Xthe window at any time. This will affect the appearance of objects drawn Xlater in the program, and is useful for drawing two or more graphs with Xdifferent axes on the same piece of paper. X X\section {Annotating the Viewport} X XThe routine \rou{plbox} is used to specify whether a frame is drawn around Xthe viewport and to control the positions of the axis subdivisions and Xnumeric labels. For our simple graph of the transistor characteristics, Xwe may wish to draw a frame consisting of lines on all four sides of the Xviewport, and to place numeric labels along the bottom and left hand side. XWe can also tell PLPLOT to choose a suitable tick interval and Xthe number of subticks between the major divisions based upon the Xdata range specified to {\tt plwind}. This is done using the following Xstatement X\begin{verbatim} Xplbox("bcnst",0.0,0,"bcnstv",0.0,0); X\end{verbatim} XAnother routine \rou{pllab} provides for text labels for the bottom, Xleft hand side and top of the viewport. These labels are not clipped, Xeven though they lie outside the viewport (but they are clipped at the Xsubpage boundaries). {\tt pllab} actually calls the more general routine X{\tt plmtex} which can be used for plotting labels at any point relative Xto the viewport. For our example, we may use X\begin{verbatim} Xpllab("V#dCE#u (Volts)","I#dC#u (mA)","TRANSISTOR CHARACTERISTICS"); X\end{verbatim} XNote that \verb+#d+ and \verb+#u+ are escape sequences (see page X\pageref{escape}) which allow Xsubscripts and superscripts to be used in text. XThey are described more Xfully later in this chapter. X XThe heights of characters used for the axis and graph labels can be Xchanged by means of the routine \rou{plschr}. X X\section {The Routine {\tt plenv}}\label{plenv-sec} X XHaving to call {\tt pladv}, {\tt plvpor}, {\tt plwind} and {\tt plbox} Xis excessively cumbersome for drawing simple graphs. Subroutine {\tt plenv} Xcombines all four of these in one subroutine, using the Xstandard viewport, and a limited subset of the capabilities of {\tt plbox}. XFor example, the graph described above could be initiated by the call: X\begin{verbatim} Xplenv(0.0,12.0,0.0,10.0,0,0); X\end{verbatim} Xwhich is equivalent to the following series of calls: X\begin{verbatim} Xpladv(0); Xplvsta(); Xplwind(0.0,12.0,0.0,10.0); Xplbox("bcnst",0.0,0,"bcnstv",0.0,0); X\end{verbatim} X X\section {Setting Line Attributes} X XThe graph drawing routines may be freely mixed with those described in Xthis section which allow the user to control line color, width and styles. XThe attributes set up by these routines apply modally, i.e, all subsequent Xobjects (lines, characters and symbols) plotted until the next change in Xattributes are affected in the same way. The only exception to this rule Xis that characters and symbols are not affected by a change in the line Xstyle, but are always drawn using a continuous line. X XLine color \label{color} is set using the routine \rou{plcol}. The Xargument is ignored for devices which can only plot in one color but some Xterminals support line erasure by plotting in color zero. X XLine width \label{width} is set using \rou{plwid}. This option is not Xsupported by all devices. X XLine style \label{style} is set using the routine \rou{plstyl} Xor \rou{pllsty}. A broken Xline is specified in terms of a repeated pattern consisting of marks X(pen down) and spaces (pen up). The arguments to this routine are Xthe number of elements in the line, followed by two pointers to Xinteger arrays specifying Xthe mark and space lengths in micrometers. Thus a line consisting of Xlong and short dashes of lengths 4\,mm and 2\,mm, separated by spaces of Xlength 1.5\,mm is specified by: X\begin{verbatim} Xmark[0]=4000; Xmark[1]=2000; Xspace[0]=1500; Xspace[1]=1500; Xplstyl(2,mark,space); X\end{verbatim} XTo return to a continuous line, just call {\tt plstyl} with first argument Xset to zero. You can use {\tt pllsty} to chose between 8 different Xpredefined styles. X X\section {Setting the Area Fill Pattern} XThe routine \rou{plpat} can be used to set the area fill pattern. The Xpattern consists of 1 or 2 sets of parallel lines with specified Xinclinations and spacings. The arguments to this routine are the Xnumber of sets to use (1 or 2) followed by two pointers to integer Xarrays (of 1 or 2 elements) specifying the inclinations in tenths Xof a degree and the spacing in micrometers. (The inclination should Xbe between -900 and 900.) Thus to specify an area fill pattern consisting Xof horizontal lines spaced 2\,mm apart use: X\begin{verbatim} X*inc=0; X*del=2000; Xplpat(1,inc,del); X\end{verbatim} XTo set up a symmetrical crosshatch pattern with lines directed 30 degrees Xabove and below the horizontal and spaced 1.5\,mm apart use: X\begin{verbatim} X*inc=300; X*(inc+1)=-300; X*del=1500; X*(del+1)=1500; Xplpat(2,inc,del); X\end{verbatim} X XThe routine \rou{plpsty} can be used to select from 1 of 8 predefined Xpatterns. X XThe area fill routines also use the current line style, width and Xcolors to give a virtually infinite number of different patterns! X X\section {Setting Character and Symbol Attributes} X XThere are two character sets included with PLPLOT. These are known as Xthe standard and extended character sets respectively. The standard Xcharacter set is a subset of the extended set. It contains 177 Xcharacters including the ascii characters in a normal style font, Xthe greek alphabet and several plotter symbols. The extended character Xset contains almost 2000 characters, including four font styles, Xand several math, musical and plotter symbols. X XThe standard character set is loaded into memory automatically when X{\tt plstar} or {\tt plbeg} is called. The extended character set Xis loaded by calling \rou{plfontld}. (The extended character set eats Xup about 50 kbytes of memory whereas the standard set takes Xup about 5 kbytes.) {\tt plfontld} can be used to switch between the Xextended and standard sets. (One set is unloaded before the next is Xloaded.) X XWhen the extended character set is loaded there are four different Xfont styles to choose from. In this case, Xthe routine \rou{plfont} sets up the default font for all character Xstrings. It may be over-ridden for (a portion) of a string by using an Xescape sequence within the text, as described below. XThe default font (1) is simple and fastest to draw, Xthe others are useful for presentation plots on a high-resolution Xdevice. X XThe font codes are interpreted as follows: X\begin{itemize} X \item{\tt font = 1}: normal simple font X \item{\tt font = 2}: roman font X \item{\tt font = 3}: italic font X \item{\tt font = 4}: script font X\end{itemize} X XThe routine \rou{plschr} is used to set up the size of subsequent Xcharacters drawn. The actual height of a character is the product of the Xdefault character size and a scaling factor. If no call is made to X{\tt plschr}, the default character size is set up depending on the number Xof subpages defined in the call to {\tt plstar} or {\tt plbeg}, and the Xscale is set to X1.0. Under normal circumstances, it is recommended that the user does not Xalter the default height, but simply use the scale parameter. This can Xbe done by calling {\tt plschr} with {\tt def=0.0} and {\tt scale} set to the Xdesired multiple of the default height. If the default height is to be Xchanged, {\tt def} is set to the new default height in millimetres, and Xthe new character height is again set to {\tt def} multiplied by {\tt Xscale}. X XThe routine \rou{plssym} sets up the size of all subsequent symbols Xdrawn by calls to {\tt plpoin} and {\tt plsym}. It operates analogously Xto {\tt plschr} as described above. X XThe lengths of major and minor ticks on the axes are set up by the routines X\rou{plsmaj} and \rou{plsmin}. X X\section {Escape Sequences in Text} \label{escape} X XThe routines which draw text all allow you to include escape Xsequences in the text to be plotted. These are character sequences Xwhich are are interpreted as instructions to Xchange fonts, draw superscripts and subscripts, draw non-ASCII X(e.g., Greek letters) etc. All escape sequences start with a number Xsymbol (\verb+#+). X XThe following escape sequences are defined: X\begin{itemize} X \item \verb+#u+: move up to the superscript position X (ended with \verb+#d+) X \item \verb+#d+: move down to subscript position X (ended with \verb+#u+) X \item \verb+#b+: backspace (to allow overprinting) X \item \verb+##+: number symbol X \item \verb.#+.: toggle overline mode X \item \verb.#-.: toggle underline mode X \item \verb+#gx+: Greek letter corresponding to Roman letter {\tt x} X (see below) X \item \verb+#fn+: switch to normal font X \item \verb+#fr+: switch to Roman font X \item \verb+#fi+: switch to italic font X \item \verb+#fs+: switch to script font X \item \verb+#(nnn)+: Hershey character nnn (1 to 4 decimal digits) X\end{itemize} X XSections of text can have an underline or overline appended. For example, Xthe string X\[ X{\rm\overline{S}(\underline{freq})} X\] Xis obtained by specifying \verb."#+S#+(#-freq#-)".. X XGreek letters are obtained by \verb+#g+ followed by a Roman letter. XTable~\ref{greek} shows how these letters map into Greek characters. X\begin{table} X \centering X \begin{tabular}{|l|*{12}{c|}} X \hline X Roman&A&B&G&D&E&Z&Y&H&I&K&L&M\\ X \hline X Greek&A & B & $\Gamma$ & $\Delta$ & E & Z & H & $\Theta$ & I & K & X $\Lambda$ & M \\ X \hline\hline X Roman&N&C&O&P&R&S&T&U&F&X&Q&W\\ X \hline X Greek&N & $\Xi$ & O & $\Pi$ & P & $\Sigma$ & X T & $\Upsilon$ & $\Phi$ & X & $\Psi$ & $\Omega$ \\ X \hline\hline X Roman&a&b&g&d&e&z&y&h&i&k&l&m\\ X \hline X Greek& $\alpha$ & $\beta$ & $\gamma$ & $\delta$ & $\epsilon$ & $\zeta$ & X $\eta$ & $\theta$ & $\iota$ & $\kappa$ & X $\lambda$ & $\mu$ \\ X \hline\hline X Roman&n&c&o&p&r&s&t&u&f&x&q&w\\ X \hline X Greek& $\nu$ & $\xi$ & o & $\pi$ & $\rho$ & $\sigma$ & X $\tau$ & $\upsilon$ & $\phi$ & $\chi$ & $\psi$ & $\omega$ \\ X \hline X \end{tabular} X\caption{Roman characters corresponding to Greek characters} X\label{greek} X\end{table} X X\section {Three Dimensional Surface Plots} \label{threed} X XPLPLOT includes routines that will represent a single-valued function Xof two variables as a surface. In this section, we shall assume that Xthe function to be plotted is {\tt Z[X][Y]}, where {\tt Z} represents Xthe dependent variable and {\tt X} and {\tt Y} represent the independent Xvariables. X XAs usual, we would like to refer to a three dimensional point {\tt (X,Y,Z)} Xin terms of some meaningful user-specified coordinate system. These are Xcalled {\em three-dimensional world coordinates}. We need to specify the Xranges of these coordinates, so that the entire surface is contained within the Xcuboid defined by ${\tt xmin}<{\tt x}<{\tt xmax}$, X${\tt ymin}<{\tt y}<{\tt ymax}$ and X${\tt zmin}<{\tt z}<{\tt zmax}$. Typically, we shall want to view the Xsurface from a variety of angles, and to facilitate this, a two-stage Xmapping of the enclosing cuboid is performed. Firstly, it is mapped Xinto another cuboid called the {\em normalized box} whose size must also Xbe specified by the user, and secondly this normalized box is viewed from Xa particular azimuth and elevation so that it can be projected onto the Xtwo-dimensional window. X XThis two-stage transformation process allows considerable flexibility in Xspecifying how the surface is depicted. The lengths of the sides of the Xnormalized box are independent of the world coordinate ranges of each of the Xvariables, making it possible to use ``reasonable'' viewing angles even if the Xranges of the world coordinates on the axes are very different. The size of the Xnormalized box is determined essentially by the size of the two-dimensional Xwindow into which it is to be mapped. The normalized box is centred about the Xorigin in the $x$ and $y$ directions, but rests on the plane ${\tt z=0}$. It is Xviewed by an observer located at altitude {\tt alt} and azimuth {\tt az}, where Xboth angles are measured in degrees. The altitude should be restricted to the Xrange zero to ninety degrees for proper operation, and represents the viewing Xangle above the xy plane. The azimuth is defined so that when {\tt az=0}, the Xobserver sees the xz plane face on, and as the angle is increased, the observer Xmoves clockwise around the box as viewed from above the xy plane. The azimuth Xcan take on any value. X XThe first step in drawing a surface plot is to decide on the size of the Xtwo-dimensional window and the normalized box. For example, we could choose Xthe normalized box to have sides of length X\begin{verbatim} Xbasex=2.0; Xbasey=4.0; Xheight=3.0; X\end{verbatim} XA reasonable range for the $x$ coordinate of the two-dimensional Xwindow is -2.5 to +2.5, since the length of the diagonal across the base of Xthe normalized box is $\sqrt{2^2+4^2} = 2\sqrt{5}$, which fits into this Xcoordinate range. A reasonable range for the $y$ coordinate of the two Xdimensional window in this case is -2.5 to +4, as the the projection of the Xnormalized box lies in this range for the allowed range of viewing angles. X XThe routine \rou{plwind} or \rou{plenv} is used in the usual way Xto establish the size of the two-dimensional window. The routine X\rou{plw3d} must then be called to establish the range of the three Xdimensional world coordinates, the size of the normalized box and the Xviewing angles. After calling {\tt plw3d}, the actual surface is Xdrawn by a call to \rou{plot3d}. X XFor example, if the three-dimensional world-coordinate ranges are X$-10.0\le{\tt x}\le 10.0$, $-3.0\le{\tt y}\le +7.0$ and X$0.0\le{\tt z}\le 8.0$, we could use the following statements: X\begin{verbatim} X xmin2d = -2.5; X xmax2d = 2.5; X ymin2d = -2.5; X ymax2d = 4.0; X plenv(xmin2d,xmax2d,ymin2d,ymax2d); X basex = 2.0; X basey = 4.0; X height = 3.0; X xmin = -10.0; X xmax = 10.0; X ymin = -3.0; X ymax = 7.0; X zmin = 0.0; X zmax = 8.0; X alt = 45.0; X az = 30.0; X side = 1; X plw3d(basex,basey,height,xmin,xmax,ymin,ymax,zmin,zmax,alt,az); X plot3d(x,y,z,ly,nx,ny,opt,side); X\end{verbatim} X XThe values of the function are stored in a two-dimensional Xarray {\tt z[][ly]} where the array element {\tt z[i][j]} contains the value Xof the function at the point $x_i$, $y_j$. Note that the values of Xthe independent variables $x_i$ and $y_j$ do not need to be equally spaced, Xbut they must lie on a rectangular grid. Thus two further arrays {\tt x[nx]} Xand {\tt y[ny]} are required as arguments to {\tt plot3d} to specify the Xvalues of the independent variables. The values in the arrays x and y must Xbe strictly increasing with the index. The argument {\tt opt} specifies Xhow the surface is outlined. If {\tt opt=1}, a line is drawn representing Xz as a function of x for each value of y, if {\tt opt=2}, a line is drawn Xrepresenting z as a function of y for each value of x, and if {\tt opt=3}, Xa net of lines is drawn. The first two options may be preferable if one of Xthe independent variables is to be regarded as a parameter, whilst the third Xis better for getting an overall picture of the surface. If side is equal to Xone then sides are drawn on the figure so that the graph doesn't appear to Xfloat. X XThe routine \rou{plmesh} is similar to {\tt plot3d,} except that it is Xused for drawing mesh plots. Mesh plots allow you to see both the top and Xbottom sides of a surface mesh, while 3D plots allow you to see the top Xside only (like looking at a solid object). The side option is not Xavailable with {\tt plmesh.} X XLabelling a three-dimensional or mesh plot is somewhat more complicated Xthan a two Xdimensional plot due to the need for skewing the characters in the label Xso that they are parallel to the coordinate axes. The routine \rou{plbox3} Xthus combines the functions of box drawing and labelling. Its parameters Xare described more fully in Chapter \ref{reference}. X X\section {Contour Plots}\label{contour} X XA routine is available in PLPLOT which performs a contour plot of data Xstored in a two-dimensional array. A contour following algorithm is Xused, so that it is possible to use non-continuous line styles. X XThe routine \rou{plcont} has the form X\name{plcont(z,nx,ny,kx,lx,ky,ly,clevel,nlevel,pltr)} Xwhere {\tt z} is the two-dimensional array of size ${\tt nx}\times{\tt ny}$ Xcontaining samples of the function to be contoured. The parameters X{\tt kx}, {\tt lx}, {\tt ky} and {\tt ly} specify the portion of {\tt z} Xthat is to be considered. The array {\tt clevel} of length {\tt nlevel} Xis a list of the desired contour levels. X XThe path of each contour is initially computed in terms of the values of the Xarray indicies which range from {\tt 0} to {\tt nx-1} in the Xfirst index and from X{\tt 0} to {\tt ny-1} in the second index. XBefore these can be drawn in the current Xwindow (see page \pageref{window} in Section \ref{window}), it is Xnecessary to Xconvert from these array indicies into world coordinates. This is done by Xpassing a pointer to a user-defined function to {\tt plcont}. This Xfunction pointer is the last argument {\tt pltr}. XThis function must be declared as type {\tt void} in the Xmodule which calls {\tt plcont}. This transformation function Xmust have the parameter list X\name{void pltr(x,y,tx,ty);} Xwhere {\tt (x,y)} Xis the point through which the contour runs expressed in Xterms of array indicies, and {\tt (tx,ty)} are pointers to float variables Xwhich are the world coordinates of Xthe point which corresponds to these indicies. X XOften, the transformation between array indices and world coordinates can Xbe expressed as a linear transformation. A routine is provided within the Xlibrary which can be passed to {\tt plcont} as {\tt pltr}. This Xtransformation routine is X\begin{verbatim} X X#include "plplot.h" X Xvoid xform(x,y,tx,ty) Xfloat x, y, *tx, *ty; X{ X extern float tr[]; X X *tx = tr[0]*x + tr[1]*y + tr[2]; X *ty = tr[3]*x + tr[4]*y + tr[5]; X} X\end{verbatim} XThus by setting up the values in the array {\tt tr[]}, we can Xapply an arbitrary translation, rotation and/or shear to the array before Xdrawing out the contours. By defining other transformation subroutines, Xit is possible to draw contours wrapped around polar grids etc. X XAs an example in setting up {\tt tr[]}, suppose that the array {\tt z} Xis of size $21 \times 41$ and contains the values of the function X$z[x][y]$, Xwhere $x$ ranges from 0.0 to 4.0 and $y$ ranges from -8.0 to 8.0. XFurthermore, Xlet us also suppose that the window (as defined using {\tt plenv} or X{\tt plwind}) covers this range of world coordinates. XSince we wish the index X(0,0) in array {\tt z} to map to (0.0,-8.0) and the index (20,40) to map Xto (4.0,8.0), and for there to be no skew in the axes, we should choose Xelements of {\tt tr[]} so that X\[ X \begin{array}{l@{\;=\;}l} X tx & 0.2x \\ X ty & 0.4y - 8. X \end{array} X\] Xand so {\tt tr[0]=0.2}, {\tt tr[1]=0.0}, {\tt tr[2]=0.0}, X{\tt tr[3]=0.0}, {\tt tr[4]=0.4}, {\tt tr[5]=-8.}. X END_OF_FILE if test 24805 -ne `wc -c <'docs/chapter3.tex'`; then echo shar: \"'docs/chapter3.tex'\" unpacked with wrong size! fi # end of 'docs/chapter3.tex' fi echo shar: End of archive 8 \(of 12\). cp /dev/null ark8isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 12 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Submissions to comp.sources.amiga and comp.binaries.amiga should be sent to: amiga@cs.odu.edu or amiga@xanth.cs.odu.edu ( obsolescent mailers may need this address ) or ...!uunet!xanth!amiga ( very obsolescent mailers need this address ) Comments, questions, and suggestions s should be addressed to ``amiga-request'' (only use ``amiga'' for submissions) at the above addresses.