amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (08/23/90)
Submitted-by: Anthony M. Richardson <amr@dukee.egr.duke.edu> Posting-number: Volume 90, Issue 244 Archive-name: applications/listplot/part03 #!/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 3 (of 3)." # Contents: Csrc/plotting.c # Wrapped by tadguy@abcfd20 on Wed Aug 22 21:03:22 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Csrc/plotting.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Csrc/plotting.c'\" else echo shar: Extracting \"'Csrc/plotting.c'\" \(25452 characters\) sed "s/^X//" >'Csrc/plotting.c' <<'END_OF_FILE' X/* X * plotting.c X * X * plotting routines. X * X */ X#include <stdio.h> X#include <errno.h> Xextern int errno; X#include <assert.h> X#include <string.h> X#include <ctype.h> X#include <signal.h> X#include "datatypes.h" X Xvoid ErrorExit(); X X#ifndef min X# define min(A,B) A<B? A : B X#endif X#ifndef max X# define max(A,B) A>B? A : B X#endif X Xextern bool GraphicsInProgress; X X/* GoldenRatio = (1+Sqrt(5))/2 */ X#define GOLDENRATIO 1.6180339887499 X#define ASPECTRATIO 1.0/GOLDENRATIO Xextern VALUE V_AngularUnit; Xextern VALUE V_AnnotationScale; Xextern VALUE V_AspectRatio; Xextern VALUE V_Boxed; Xextern VALUE V_Domain; Xextern VALUE V_Gridding; Xextern VALUE V_LabelScale; Xextern VALUE V_LineColor; Xextern VALUE V_LineStyle; Xextern VALUE V_Orientation; Xextern VALUE V_Origin; Xextern VALUE V_PlotColor; Xextern VALUE V_PlotDevice; Xextern VALUE V_PlotJoined; Xextern VALUE V_PlotPoints; Xextern VALUE V_PlotTitle; Xextern VALUE V_PlotType; Xextern VALUE V_PointScale; Xextern VALUE V_PointSymbol; Xextern VALUE V_PolarVariable; Xextern VALUE V_Range; Xextern VALUE V_SubPages; Xextern VALUE V_SupplyAbscissa; Xextern VALUE V_TitleScale; Xextern VALUE V_UseInputFile; Xextern VALUE V_Verbose; Xextern VALUE V_ViewPort; Xextern VALUE V_XLabel; Xextern VALUE V_XTick; Xextern VALUE V_YLabel; Xextern VALUE V_YTick; X Xchar *DeviceTypes[] = { X "amiga", X "printer", X "iff", X "hp", X "aegis", X "postscript", X (char *)NULL X}; X Xtypedef struct line_style { X int ls_type; X int ls_nelms; X int *ls_space; X int *ls_mark; X } LINESTYLE; XLIST LineStyleList; XLINESTYLE *LineStyles; int NLineStyles; Xint *PointCodes, NPointCodes; Xint space0 = 0, mark0 = 0, space1 = 1500, mark1 = 1500; X XRECT UserRect; XRECT ViewPort = { 0.1,0.1, 0.9,0.9 }; XRECT WorldRect = {0.0,0.0, 1.0,1.0}; X X Xvoid XListPlot(Data, NTuples, TupleSize) XFLOAT **Data; Xint NTuples, TupleSize; X{ X void InitializeDevice(); X void InitializePlottingEnv(); X#ifdef ANSI_C X void Plot2D(FLOAT **, int , int ); X void PolarPlot(FLOAT **, int , int ); X#else X void Plot2D(); X void PolarPlot(); X#endif X X InitializeDevice(); X GraphicsInProgress = TRUE; X X InitializePlottingEnv(Data, NTuples, TupleSize); X X if (Vstrcmp(V_PlotType,"polar")) { X PolarPlot(Data, NTuples, TupleSize); X } else { X Plot2D(Data, NTuples, TupleSize); X } X plend(); X} X X Xvoid XInitializeDevice() X{ X register int i; X register char *DeviceStr; X X X plorient(Vstrcmp(V_Orientation, "portrait")? 1 : 0); X plselect(stdout); /* write to stdout */ X X X DeviceStr = V_PlotDevice.val_u.udt_string; X for (i=0; DeviceTypes[i]; i++) X if (strcmp(DeviceStr, DeviceTypes[i]) == 0) { X plbeg( X i+1, /* device code */ X (int)V_SubPages.val_u.udt_interval.int_lo, /* nx */ X (int)V_SubPages.val_u.udt_interval.int_hi /* ny */ X ); X return; X } X fprintf(stderr,"(InitializeDevice) Unknown device type: %s\n", DeviceStr); X ErrorExit(); X} X Xvoid XInitializePlottingEnv(Data, NTuples, TupleSize) XFLOAT **Data; Xint NTuples; Xint TupleSize; X{ X int i, j; X FLOAT *Ptr; X void InitLineStyles(); X void InitPointCodes(); X X /* viewport */ X ViewPort = VtoRect(V_ViewPort); X X /* user window */ X UserRect.XMin = MAX_FLOAT; X UserRect.YMin = MAX_FLOAT; X UserRect.XMax = -MAX_FLOAT; X UserRect.YMax = -MAX_FLOAT; X X if (VtoBoolean(V_SupplyAbscissa)) { X UserRect.XMin = 0.0; X UserRect.XMax = (FLOAT)(NTuples-1); X } else { X for (i=0; i<NTuples; i++) { X if (Data[i][0] < UserRect.XMin) X UserRect.XMin = Data[i][0]; X if (Data[i][0] > UserRect.XMax) X UserRect.XMax = Data[i][0]; X } X } X for (i=0; i<NTuples; i++) X for (j=TupleSize-1,Ptr= &Data[i][1]; j>0; --j,Ptr++) { X if (*Ptr < UserRect.YMin) X UserRect.YMin = *Ptr; X if (*Ptr > UserRect.YMax) X UserRect.YMax = *Ptr; X } X X X /* font scaling */ X X /* plot type */ X X /* grid */ X X /* line styles */ X InitLineStyles(); X X X /* line colors */ X X /* point symbols */ X InitPointCodes(); X X /* window type */ X X /* X label */ X X /* Y label */ X X /* Plot title */ X X /* aspect ratio */ X} X X#define isMark(C) (((C) == 'M' || (C) == 'm')? TRUE : FALSE) X#define isSpace(C) (((C) == 'S' || (C) == 's')? TRUE : FALSE) X#define MarkLength(C) (C) == 'M'? 1000 : 250 X#define SpaceLength(C) (C) == 'S'? 1000 : 250 X#define MAX_MARKS 32 X Xvoid XDecodeLineStyle(StyleStr, Mark, Space, N) Xchar *StyleStr; Xint **Mark; Xint **Space; Xint *N; X{ X register char *S; X int macc, sacc; X int i, j, k; X int mark[MAX_MARKS]; X int space[MAX_MARKS]; X bool ProcessingMark; X X /* X * 'S' = 1000 micron space X * 's' = 250 micron space X * 'M' = 1000 micron line X * 'm' = 250 micron line X */ X ProcessingMark = TRUE; /* to satisfy some compilers */ X if (isMark(*StyleStr)) X ProcessingMark = TRUE; X else if (isSpace(*StyleStr)) X ProcessingMark = FALSE; X else { X fprintf(stderr,"(DecodeLineStyle) Invalid Line style: \"%s\"\n", StyleStr); X ErrorExit(); X } X memset((char *)mark, 0, MAX_MARKS * sizeof(int)); X memset((char *)space, 0, MAX_MARKS * sizeof(int)); X for (macc=0,sacc=0,i=0,j=0,S=StyleStr ; *S && i<MAX_MARKS && j<MAX_MARKS; ++S) { X if (isMark(*S) && ProcessingMark) { X macc += MarkLength(*S); X } else if (isMark(*S) && !ProcessingMark) { X space[j++] = sacc; X macc = MarkLength(*S); X ProcessingMark = TRUE; X } else if (isSpace(*S) && ProcessingMark) { X mark[i++] = macc; X sacc = SpaceLength(*S); X ProcessingMark = FALSE; X } else if (isSpace(*S) && !ProcessingMark) { X sacc += SpaceLength(*S); X } else if (isspace(*S)) { X continue; X } else { X fprintf(stderr,"(DecodeLineStyle) Invalid line style code '%c' in \"%s\"\n", *S, StyleStr); X ErrorExit(); X } X } X if (ProcessingMark) X mark[i++] = macc; X else X space[j++] = sacc; X X k = max(i,j); X X if (((*Mark) = (int *)calloc(k, sizeof(int))) == (int *)NULL) { X perror("(DecodeLineStyle) "); X ErrorExit(); X } X if (((*Space) = (int *)calloc(k, sizeof(int))) == (int *)NULL) { X perror("(DecodeLineStyle) "); X ErrorExit(); X } X for (i=0; i<k; i++) { X (*Mark)[i] = mark[i]; X (*Space)[i] = space[i]; X } X *N = k; X} X Xvoid XInitLineStyles() X{ X int i; X LATOM *A; X LINESTYLE *LS; X int *Mark, *Space; X int N; X#ifdef ANSI_C X LINESTYLE *LSAlloc(int , int *, int *); X#else X LINESTYLE *LSAlloc(); X#endif X X LineStyleList.list_n = 0; X LineStyleList.list_head = (LATOM *)NULL; X LineStyleList.list_tail = (LATOM *)NULL; X X LS = LSAlloc(0, (int *)NULL, (int *)NULL); X Append(&LineStyleList, (generic *)LS); X X for (i=1,A=V_LineStyle.val_u.udt_set.list_head; A; A=A->la_next,i++) { X DecodeLineStyle( X (char *)A->la_p, X &Mark, X &Space, X &N X ); X LS = LSAlloc(N, Mark, Space); X Append(&LineStyleList, (generic *)LS); X } X X NLineStyles = i; X if ((LineStyles = (LINESTYLE *)calloc(NLineStyles, sizeof(LINESTYLE))) == (LINESTYLE *)NULL) { X perror("(InitLineStyles) "); X ErrorExit(); X } X for (i=0,A=LineStyleList.list_head; A; A=A->la_next,i++) { X LineStyles[i].ls_mark = ((LINESTYLE *)(A->la_p))->ls_mark; X LineStyles[i].ls_space = ((LINESTYLE *)(A->la_p))->ls_space; X LineStyles[i].ls_nelms = ((LINESTYLE *)(A->la_p))->ls_nelms; X } X} X X XLINESTYLE * XLSAlloc(n, Mark, Space) Xint n; Xint *Mark, *Space; X{ X register LINESTYLE *LS; X X if ((LS = (LINESTYLE *)calloc(1, sizeof(LINESTYLE))) == (LINESTYLE *)NULL) { X perror("(LSAlloc) "); X assert(LS != (LINESTYLE *)NULL); X exit(errno); X } X LS->ls_mark = Mark; X LS->ls_space = Space; X LS->ls_nelms = n; X return(LS); X} X Xvoid XInitPointCodes() X{ X register LATOM *A; X register int i; X extern int *PointCodes, NPointCodes; X extern VALUE V_PointSymbol; X X if (!isSet(V_PointSymbol)) { X NPointCodes = 0; X return; X } X X /* count # codes */ X for (i=0,A=V_PointSymbol.val_u.udt_set.list_head; A; A=A->la_next, i++) X ; X X NPointCodes = i; X if (NPointCodes == 0) X return; X X if ((PointCodes = (int *)calloc(NPointCodes, sizeof(int))) == (int *)NULL) { X perror("(InitPointCodes) "); X assert(PointCodes != (int *)NULL); X ErrorExit(); X } X for (i=0,A=V_PointSymbol.val_u.udt_set.list_head; A; A=A->la_next, i++) { X PointCodes[i] = atoi((char *)A->la_p); X } X} X X Xvoid XPlot2D(Data, NTuples, TupleSize) XFLOAT **Data; Xint NTuples; Xint TupleSize; X{ X int i, j; X FLOAT *X, *Y; X FLOAT x, y; X FLOAT x0, y0; X FLOAT xtick, ytick; X FLOAT Xmin,Xmax, Ymin,Ymax; X FLOAT MedianX, StdDevX; X FLOAT MedianY, StdDevY; X int nxsub, nysub; X bool AutoRange, AutoDomain; X bool LogX, LogY; X char Xopt[16], Yopt[16]; X#ifdef ANSI_C X void StatisticsOfX( X FLOAT **, X int, X int , X FLOAT *, X FLOAT * X ); X void StatisticsOfY( X FLOAT **, X int, X int , X FLOAT *, X FLOAT * X ); X double log10(double); X#else X void StatisticsOfX(); X void StatisticsOfY(); X double log10(); X#endif X X pladv(0); X ViewPort = VtoRect(V_ViewPort); X X if (isString(V_AspectRatio)) { X /* automatic --> STRETCH */ X plvpor(ViewPort.XMin, ViewPort.XMax, ViewPort.YMin, ViewPort.YMax); X/*debug X plvsta(); Xdebug*/ X } else { X assert(isDbl(V_AspectRatio)); X plvasp(VtoDbl(V_AspectRatio)); X } X X LogX = (Vstrcmp(V_PlotType, "loglin") || Vstrcmp(V_PlotType,"loglog"))? X TRUE : FALSE; X LogY = (Vstrcmp(V_PlotType, "linlog") || Vstrcmp(V_PlotType,"loglog"))? X TRUE : FALSE; X X /* window bounds */ X AutoDomain = FALSE; X if (isString(V_Domain) && Vstrcmp(V_Domain, "All")) { X /* all points */ X Xmin = UserRect.XMin; X Xmax = UserRect.XMax; X } else if (isString(V_Domain) && Vstrcmp(V_Domain,"Automatic")) { X /* automatic */ X AutoDomain = TRUE; X StatisticsOfX(Data, NTuples, TupleSize, &MedianX, &StdDevX); X x = MedianX - 3.0*StdDevX; X Xmin = UserRect.XMin < x? x : UserRect.XMin; X x = MedianX + 3.0*StdDevX; X Xmax = UserRect.XMax > x? x : UserRect.XMax; X } else { X assert(isInterval(V_Domain)); X Xmin = V_Domain.val_u.udt_interval.int_lo; X Xmax = V_Domain.val_u.udt_interval.int_hi; X } X if (LogX) { X if (Xmin == 0.0 || Xmax == 0.0) { X /* error */ X fprintf(stderr,"ListPlot: Trying to find log10(0) in data! Stop.\n"); X ErrorExit(); X } X Xmin = log10((double)Xmin); X Xmax = log10((double)Xmax); X } X X AutoRange = FALSE; X if (isString(V_Range) && Vstrcmp(V_Range, "All")) { X /* all */ X Ymin = UserRect.YMin; X Ymax = UserRect.YMax; X } else if (isString(V_Range) && Vstrcmp(V_Range,"Automatic")) { X /* automatic */ X AutoRange = TRUE; X StatisticsOfY(Data, NTuples, TupleSize, &MedianY, &StdDevY); X y = MedianY - 3.0*StdDevY; X Ymin = UserRect.YMin < y? y : UserRect.YMin; X y = MedianY + 3.0*StdDevY; X Ymax = UserRect.YMax > y? y : UserRect.YMax; X } else { X assert(isInterval(V_Range)); X Ymin = V_Range.val_u.udt_interval.int_lo; X Ymax = V_Range.val_u.udt_interval.int_hi; X } X if (LogY) { X if (Ymin == 0.0 || Ymax == 0.0) { X /* error */ X fprintf(stderr,"ListPlot: Trying to find log10(0) in data! Stop.\n"); X ErrorExit(); X } X Ymin = log10((double)Ymin); X Ymax = log10((double)Ymax); X } X plwind( X Xmin, X Xmax, X Ymin, X Ymax X ); X plschr(0., VtoDbl(V_AnnotationScale)); X X X /* X and Y ticks */ X if (isString(V_XTick)) { X /* automatic */ X xtick = 0.; X nxsub = 0; X } else { X xtick = V_XTick.val_u.udt_interval.int_lo; X if (LogX) xtick = log10((double)xtick); X nxsub = V_XTick.val_u.udt_interval.int_hi; X } X if (isString(V_YTick)) { X /* automatic */ X ytick = 0.; X nysub = 0; X } else { X ytick = V_YTick.val_u.udt_interval.int_lo; X if (LogY) ytick = log10((double)ytick); X nysub = V_YTick.val_u.udt_interval.int_hi; X } X X /* Axis options */ X Xopt[0] = (char)NULL; X Yopt[0] = (char)NULL; X if (isBoolean(V_Boxed) && VtoBoolean(V_Boxed)) { X strcat(Xopt, "bc"); X strcat(Yopt, "bc"); X } else if (isString(V_Boxed)) { X if (Vstrchr(V_Boxed, 'b')) X strcat(Xopt, "b"); X if (Vstrchr(V_Boxed, 't')) X strcat(Xopt, "c"); X if (Vstrchr(V_Boxed, 'r')) X strcat(Yopt, "c"); X if (Vstrchr(V_Boxed, 'l')) X strcat(Yopt, "b"); X } else { X ; X } X if (LogX) X strcat(Xopt, "l"); X if (LogY) X strcat(Yopt, "l"); X strcat(Xopt, "nst"); X strcat(Yopt, "nstv"); X X if (isString(V_Origin) && Vstrcmp(V_Origin, "Median")) { X if (AutoDomain == FALSE) { X StatisticsOfX(Data,NTuples,TupleSize,&MedianX,&StdDevX); X } X if (AutoRange == FALSE) { X StatisticsOfY(Data,NTuples,TupleSize,&MedianY,&StdDevY); X } X plaxes( X MedianX,MedianY, X Xopt, xtick, nxsub, X Yopt, ytick,nysub X ); X } else if (isInterval(V_Origin)) { X x0 = V_Origin.val_u.udt_interval.int_lo; X y0 = V_Origin.val_u.udt_interval.int_hi; X plaxes( X x0,y0, X Xopt, xtick, nxsub, X Yopt, ytick,nysub X ); X } else if (isString(V_Origin) && Vstrcmp(V_Origin, "Automatic")) { X plbox(Xopt, xtick, nxsub, Yopt, ytick,nysub); X } else { X plbox(Xopt, xtick, nxsub, Yopt, ytick,nysub); X } X X /* gridding */ X if (VtoBoolean(V_Gridding)) { X /* gridding on */ X plstyl(1, &mark1, &space1); X plbox("g", xtick, nxsub, "g", ytick,nysub); X plstyl(0, &mark0, &space0); X } X X /* plot curves */ X if ((X = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) { X perror("(Plot2D) "); X ErrorExit(); X } X if ((Y = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) { X perror("(Plot2D) "); X ErrorExit(); X } X if (VtoBoolean(V_SupplyAbscissa)) { X for (i=0; i<NTuples; i++) X X[i] = LogX? log10((double)(i+1)) : (FLOAT)i; X } else { X for (i=0; i<NTuples; i++) X X[i] = LogX? log10((double)Data[i][0]) : Data[i][0]; X } X for (i=1; i<TupleSize; i++) { X if (NLineStyles > 0) { X /* use user-supplied patterns */ X plstyl( X LineStyles[(i-1)%NLineStyles].ls_nelms, X LineStyles[(i-1)%NLineStyles].ls_mark, X LineStyles[(i-1)%NLineStyles].ls_space X ); X } else { X pllsty((i-1)%8 + 1); X } X plcol(i); X for (j=0; j<NTuples; j++) X Y[j] = LogY? log10((double)Data[j][i]) : Data[j][i]; X X if (VtoBoolean(V_PlotJoined)) X plline(NTuples, X, Y); X X if (VtoBoolean(V_PlotPoints)) { X plschr(0., VtoDbl(V_PointScale)); X pllsty(1); X if (NPointCodes > 0) { X plpoin(NTuples, X, Y, PointCodes[(i-1)%NPointCodes]); X } else { X plpoin(NTuples, X, Y, i); X } X } X } X X X /* restore line styles etc... */ X pllsty(1); X plcol(1); X plschr(0., VtoDbl(V_LabelScale)); X pllab(VtoString(V_XLabel), VtoString(V_YLabel), ""); X plschr(0., VtoDbl(V_TitleScale)); X pllab("","", VtoString(V_PlotTitle)); X} X X#define DTR(D) (double)((D)*3.1415927/180.0) X Xvoid XPolarPlot(Data, NTuples, TupleSize) XFLOAT **Data; Xint NTuples; Xint TupleSize; X{ X int i, j; X FLOAT *A, *R; X FLOAT x, y; X FLOAT xtick, ytick; X FLOAT atick, rtick; X FLOAT Xmin,Xmax, Ymin,Ymax; X FLOAT r, rmax, ang, amax; X FLOAT MedianX, StdDevX; X FLOAT MedianY, StdDevY; X FLOAT da; X FLOAT x0,y0, xn,yn; X double pi; X char s[32]; X int nxsub, nysub, nrsub, nasub; X bool InRadians, XisAngular; X bool AutoDomain, AutoRange; X#ifdef ANSI_C X void StatisticsOfX( X FLOAT **, X int , X int , X FLOAT *, X FLOAT * X ); X void StatisticsOfY( X FLOAT **, X int , X int , X FLOAT *, X FLOAT * X ); X double log10(double); double fabs(); X double sqrt(), sin(), cos(), atan(); X#else X void StatisticsOfX(); X void StatisticsOfY(); X double log10(); double fabs(); X double sqrt(), sin(), cos(), atan(); X#endif X X pi = 4.0 * atan((double)1.0); X InRadians = Vstrcmp(V_AngularUnit, "degrees")? FALSE : TRUE; X XisAngular = Vstrcmp(V_PolarVariable,"angle")? TRUE : FALSE; X X pladv(0); X X if (isString(V_AspectRatio)) { X /* automatic --> STRETCH */ X plvasp(1.0); X } else { X assert(isDbl(V_AspectRatio)); X plvasp(VtoDbl(V_AspectRatio)); X } X X /* window bounds */ X AutoDomain = FALSE; X if (isString(V_Domain) && Vstrcmp(V_Domain, "All")) { X /* all points */ X Xmin = UserRect.XMin; X Xmax = UserRect.XMax; X } else if (isString(V_Domain) && Vstrcmp(V_Domain,"Automatic")) { X /* automatic */ X AutoDomain = TRUE; X StatisticsOfX(Data, NTuples, TupleSize, &MedianX, &StdDevX); X x = MedianX - 3.0*StdDevX; X Xmin = UserRect.XMin < x? x : UserRect.XMin; X x = MedianX + 3.0*StdDevX; X Xmax = UserRect.XMax > x? x : UserRect.XMax; X } else { X assert(isInterval(V_Domain)); X Xmin = V_Domain.val_u.udt_interval.int_lo; X Xmax = V_Domain.val_u.udt_interval.int_hi; X } X X AutoRange = FALSE; X if (isString(V_Range) && Vstrcmp(V_Range, "All")) { X /* all */ X Ymin = UserRect.YMin; X Ymax = UserRect.YMax; X } else if (isString(V_Range) && Vstrcmp(V_Range,"Automatic")) { X /* automatic */ X AutoRange = TRUE; X StatisticsOfY(Data, NTuples, TupleSize, &MedianY, &StdDevY); X y = MedianY - 3.0*StdDevY; X Ymin = UserRect.YMin < y? y : UserRect.YMin; X y = MedianY + 3.0*StdDevY; X Ymax = UserRect.YMax > y? y : UserRect.YMax; X } else { X assert(isInterval(V_Range)); X Ymin = V_Range.val_u.udt_interval.int_lo; X Ymax = V_Range.val_u.udt_interval.int_hi; X } X rmax = XisAngular? Ymax : Xmax; X plwind( X -1.3*rmax, X 1.3*rmax, X -1.3*rmax, X 1.3*rmax X ); X X X /* X and Y ticks */ X if (isString(V_XTick)) { X /* automatic */ X xtick = XisAngular? (InRadians? pi/6.0 : 30.0) : 0.25 * rmax; X nxsub = 4; X } else { X xtick = V_XTick.val_u.udt_interval.int_lo; X nxsub = V_XTick.val_u.udt_interval.int_hi; X } X if (isString(V_YTick)) { X /* automatic */ X ytick = XisAngular? 0.25 * rmax : (InRadians? pi/6.0 : 30.0); X nysub = 4; X } else { X ytick = V_YTick.val_u.udt_interval.int_lo; X nysub = V_YTick.val_u.udt_interval.int_hi; X } X rtick = XisAngular? ytick : xtick; X atick = XisAngular? xtick : ytick; X nasub = XisAngular? nxsub : nysub; X nrsub = XisAngular? nysub : nxsub; X amax = InRadians? 2.0 * pi : 360.0; X X /* Axis options */ X if (VtoBoolean(V_Gridding)) { X /* draw circles */ X plstyl(0, &mark1, space1); X /* circular ticks */ X for (i=0,r=(rtick/nrsub); r<rmax; r += (rtick/nrsub),i++) { X da = i%nrsub? 0.05 * atick : 0.1 * atick; X for (ang=0; ang<amax; ang += atick) { X x0 = r * cos(InRadians? ang-da : DTR(ang-da)); X y0 = r * sin(InRadians? ang-da : DTR(ang-da)); X xn = r * cos(InRadians? ang+da : DTR(ang+da)); X yn = r * sin(InRadians? ang+da : DTR(ang+da)); X pljoin(x0,y0,xn,yn); X } X } X#ifdef CIRCULAR_TICKS X /* major circles */ X for (r=rtick; r<rmax; r += rtick) { X x0 = r; y0 = 0.0; X for (ang=1.0; ang<=360.0; ang++) { X xn = r * cos((double)(DTR(ang))); X yn = r * sin((double)(DTR(ang))); X pljoin(x0,y0,xn,yn); X x0 = xn; y0 = yn; X } X } X#endif X /* draw spokes */ X for (i=0,ang=0.0; ang<amax; ang += (atick/nasub),i++) { X xn = rmax * cos(InRadians? ang : DTR(ang)); X yn = rmax * sin(InRadians? ang : DTR(ang)); X if (i%nasub == 0) { X pljoin((FLOAT)0.0,(FLOAT)0.0,xn,yn); X } else { X pljoin(xn,yn,1.05*xn,1.05*yn); X } X } X } X /* write angle labels */ X plschr(0., VtoDbl(V_AnnotationScale)); X j = amax / atick; X for (ang=0.0,i=0; i<j; ang += atick,i++) { X if (InRadians) { X xn = rmax * cos((double)ang); X yn = rmax * sin((double)ang); X if (fabs(ang-(2.0*pi)) > 1.0e-2) X sprintf(s, "%.2f #gp", (float)ang/pi); X } else { X xn = rmax * cos((double)DTR(ang)); X yn = rmax * sin((double)DTR(ang)); X sprintf(s, "%d", (int)(ang+0.5)); X } X if (xn >= 0) X plptex(xn,yn,xn,yn,-0.15, s); X else X plptex(xn,yn,-xn,-yn,1.15, s); X } X plstyl(0, &mark0, &space0); X X /* plot curves */ X if ((A = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) { X perror("(Plot2D) "); X ErrorExit(); X } X if ((R = (FLOAT *)calloc(NTuples, sizeof(FLOAT))) == (FLOAT *)NULL) { X perror("(Plot2D) "); X ErrorExit(); X } X if (VtoBoolean(V_SupplyAbscissa)) { X for (i=0; i<NTuples; i++) X if (XisAngular) X A[i] = i*2.0*pi/(NTuples-1); X else X R[i] = i*rmax/(NTuples-1); X } else { X for (i=0; i<NTuples; i++) X if (XisAngular) X A[i] = InRadians? Data[i][0] : DTR(Data[i][0]); X else X R[i] = Data[i][0]; X } X for (i=1; i<TupleSize; i++) { X if (NLineStyles > 0) { X /* use user-supplied patterns */ X plstyl( X LineStyles[(i-1)%NLineStyles].ls_nelms, X LineStyles[(i-1)%NLineStyles].ls_mark, X LineStyles[(i-1)%NLineStyles].ls_space X ); X } else { X pllsty((i-1)%8); X } X plcol(i); X X /* get and convert data if necessary */ X if (InRadians && !XisAngular) X for (j=0; j<NTuples; j++) X A[j] = Data[j][i]; X else if ((!InRadians) && !XisAngular) X for (j=0; j<NTuples; j++) X A[j] = DTR(Data[j][i]); X else X for (j=0; j<NTuples; j++) X R[j] = Data[j][i]; X X /* convert to cartesian A<->X R<->Y*/ X for (j=0; j<NTuples; j++) { X x0 = R[j] * cos(A[j]); X y0 = R[j] * sin(A[j]); X A[j] = x0; X R[j] = y0; X } X if (VtoBoolean(V_PlotJoined)) { X x0 = A[0]; X y0 = R[0]; X for (j=1; j<NTuples; j++) { X pljoin(A[j-1], R[j-1], A[j],R[j]); X } X } X X if (VtoBoolean(V_PlotPoints)) { X plschr(0., VtoDbl(V_PointScale)); X pllsty(1); X if (NPointCodes > 0) { X plpoin(NTuples, A, R, PointCodes[(i-1)%NPointCodes]); X } else { X plpoin(NTuples, A, R, i); X } X } X } X X /* restore line styles etc... */ X pllsty(1); X plcol(1); X plschr(0., VtoDbl(V_LabelScale)); X pllab(VtoString(V_XLabel), VtoString(V_YLabel), ""); X plschr(0., VtoDbl(V_TitleScale)); X pllab("","", VtoString(V_PlotTitle)); X} X X Xvoid XStatisticsOfX(Data, NTuples,TupleSize, Median, StdDev) XFLOAT **Data; Xint NTuples; Xint TupleSize; XFLOAT *Median; XFLOAT *StdDev; X{ X#ifdef ANSI_C X FLOAT MedianOfX(); X FLOAT StdDevOfX(); X/*debug X FLOAT MedianOfX(FLOAT **Data,int NTuples,int TupleSize); X FLOAT StdDevOfX(FLOAT **Data,int NTuples,int TupleSize); Xdebug*/ X#else X FLOAT MedianOfX(); X FLOAT StdDevOfX(); X#endif X *StdDev = StdDevOfX(Data,NTuples,TupleSize); X *Median = MedianOfX(Data,NTuples,TupleSize); X} X X Xvoid XStatisticsOfY(Data, NTuples,TupleSize, Median, StdDev) XFLOAT **Data; Xint NTuples; Xint TupleSize; XFLOAT *Median; XFLOAT *StdDev; X{ X#ifdef ANSI_C X FLOAT MedianOfY(); X FLOAT StdDevOfY(); X/*debug X FLOAT MedianOfY(FLOAT **Data,int NTuples,int TupleSize); X FLOAT StdDevOfY(FLOAT **Data,int NTuples,int TupleSize); Xdebug*/ X#else X FLOAT MedianOfY(); X FLOAT StdDevOfY(); X#endif X *StdDev = StdDevOfY(Data,NTuples,TupleSize); X *Median = MedianOfY(Data,NTuples,TupleSize); X} X X XFLOAT XStdDevOfX(Data,NTuples,TupleSize) XFLOAT **Data; Xint NTuples; Xint TupleSize; X{ X int i; X FLOAT StdDev, x; X FLOAT var, sum, mean; X double sqrt(), fabs(); X X if (VtoBoolean(V_SupplyAbscissa)) { X return((FLOAT)(NTuples*NTuples)/12.0); X } X X sum = 0.0; X for (i=0; i<NTuples; i++) X sum += Data[i][0]; X mean = sum / NTuples; X X var = 0.0; X for (i=0; i<NTuples; i++) { X x = fabs((double)(Data[i][0] - mean)); X var += x * x; X } X var /= (NTuples-1); X StdDev = sqrt((double)var); X return(StdDev); X} X X XFLOAT XStdDevOfY(Data,NTuples,TupleSize) XFLOAT **Data; Xint NTuples; Xint TupleSize; X{ X int i,j,D; X FLOAT StdDev, x; X FLOAT var, sum, mean; X FLOAT n; X double sqrt(), fabs(); X X D = VtoBoolean(V_SupplyAbscissa) ? 0 : 1; X n = NTuples * (TupleSize-D); X sum = 0.0; X for (i=0; i<NTuples; i++) X for (j=D; j<TupleSize; j++) { X sum += Data[i][j]; X } X mean = sum / n; X X var = 0.0; X for (i=0; i<NTuples; i++) X for (j=D; j<TupleSize; j++) { X x = fabs((double)(Data[i][j] - mean)); X var += x * x; X } X var /= (n-1); X StdDev = sqrt((double)var); X return(StdDev); X} X X#define BIG 1.0e30 X#define AFAC 1.5 X#define AMP 1.5 X XFLOAT XMedianOfX(Data,NTuples,TupleSize) XFLOAT **Data; Xint NTuples; Xint TupleSize; X/* an iterative computation of the median... X * Code taken from Numerical Recipes.. X */ X{ X int np, nm, i; X FLOAT xx,xp,xm,sumx,sum,eps,stemp,dum,ap,am,aa,a; X FLOAT Median; X double fabs(); X X if (VtoBoolean(V_SupplyAbscissa)) X return((FLOAT)(0.5*NTuples)); X X /* first estimate */ X a = 0.5 * (Data[0][0] + Data[NTuples-1][0]); X eps = fabs((double)(Data[NTuples-1][0] - Data[0][0])); X X am = -(ap=BIG); X for (;;) { X sum = sumx = 0.0; X np = nm = 0; /* # point above and below median */ X xm = -(xp = BIG); X X for (i=0; i<NTuples; i++) { X xx = Data[i][0]; X if (xx != a) { X if (xx > a) { X ++np; X if (xx < xp) xp = xx; X } else if (xx < a) { X ++nm; X if (xx > xm) xm = xx; X } X sum += dum=1.0/(eps+fabs((double)(xx-a))); X sumx += xx * dum; X } X } X X stemp = (sumx / sum) - a; X if ((np-nm) >= 2) { X /* guess is too low make another pass */ X am = a; X aa = stemp < 0.0? xp : xp + stemp*AMP; X if (aa > ap) aa = 0.5*(a+ap); X eps = AFAC * fabs((double)(aa-a)); X a = aa; X } else if ((nm-np) >= 2) { X /* guess is too high make another pass */ X ap = a; X aa = stemp > 0.0? xm : xm+stemp*AMP; X if (aa < am) aa = 0.5*(a+am); X eps = AFAC*fabs((double)(aa-a)); X a = aa; X } else { /* got it */ X if (NTuples%2 == 0) { X Median = 0.5*(np==nm? xp+xm : np>nm? a+xp : xm+a); X } else { X Median = np == nm? a : np>nm? xp : xm; X } X return(Median); X } X } X} X XFLOAT XMedianOfY(Data,N,M) XFLOAT **Data; Xint N; Xint M; X/* an iterative computation of the median... X * Code taken from Numerical Recipes.. X */ X{ X int n, np, nm, i,j,D; X FLOAT xx,xp,xm,sumx,sum,eps,stemp,dum,ap,am,aa,a; X FLOAT Median; X double fabs(); X X D = VtoBoolean(V_SupplyAbscissa) ? 0 : 1; X n = N * (M-D); X X /* first estimate */ X a = 0.5 * (Data[0][D] + Data[N-1][M-1]); X eps = fabs((double)(Data[N-1][M-1] - Data[0][D])); X X am = -(ap=BIG); X for (;;) { X sum = sumx = 0.0; X np = nm = 0; /* # point above and below median */ X xm = -(xp = BIG); X X for (i=0; i<N; i++) { X for (j=D; j<M; j++) { X xx = Data[i][j]; X if (xx != a) { X if (xx > a) { X ++np; X if (xx < xp) xp = xx; X } else if (xx < a) { X ++nm; X if (xx > xm) xm = xx; X } X sum += dum=1.0/(eps+fabs((double)(xx-a))); X sumx += xx * dum; X } X } X } X X stemp = (sumx / sum) - a; X if ((np-nm) >= 2) { X /* guess is too low make another pass */ X am = a; X aa = stemp < 0.0? xp : xp + stemp*AMP; X if (aa > ap) aa = 0.5*(a+ap); X eps = AFAC * fabs((double)(aa-a)); X a = aa; X } else if ((nm-np) >= 2) { X /* guess is too high make another pass */ X ap = a; X aa = stemp > 0.0? xm : xm+stemp*AMP; X if (aa < am) aa = 0.5*(a+am); X eps = AFAC*fabs((double)(aa-a)); X a = aa; X } else { /* got it */ X if (n%2 == 0) { X Median = 0.5*(np==nm? xp+xm : np>nm? a+xp : xm+a); X } else { X Median = np == nm? a : np>nm? xp : xm; X } X return(Median); X } X } X} END_OF_FILE if test 25452 -ne `wc -c <'Csrc/plotting.c'`; then echo shar: \"'Csrc/plotting.c'\" unpacked with wrong size! fi chmod +x 'Csrc/plotting.c' # end of 'Csrc/plotting.c' fi echo shar: End of archive 3 \(of 3\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>. Mail comments to the moderator at <amiga-request@uunet.uu.net>. Post requests for sources, and general discussion to comp.sys.amiga.