fix 2 compiler warnings in modelgen
[gnucap-felix.git] / lib / plot.cc
blobc733cf114e708cf586e8bd6341a95f58e0515fd6
1 /*$Id: plot.cc,v 1.2 2010-09-07 07:46:24 felix Exp $
2 * (this file is a mess. it should be redone.)
3 */
4 //testing=script 2006.07.17
5 #include "declare.h" /* self */
6 #include "constant.h"
7 #include "u_opt.h"
8 #include "u_prblst.h"
9 /*--------------------------------------------------------------------------*/
10 void plottr(double,const PROBELIST&);
11 int plopen(double,double,const PROBELIST&);
12 void plclose(void);
13 void plclear(void);
14 static void plborder(void);
15 static void calibrate(const PROBE&);
16 static int round_to_int(double);
17 static void plhead(const PROBELIST&);
18 static int point(double,double,double,int,int,int);
19 static void plotarg(double,double,double,double,double,double,
20 double,double,double);
21 /*--------------------------------------------------------------------------*/
22 #define MAXWIDTH 512
23 #define OUTWIDTH (std::min(static_cast<int>(OPT::outwidth), MAXWIDTH))
24 #define INDENT 8 /* beware OMSTERAM::form! */
25 #define CONSSCALE (OUTWIDTH - INDENT - 2) /*console scale size in chr */
26 static bool active; /* flag: plotting has opened */
27 static double xstart, xstop;
28 static char border[MAXWIDTH+1]; /* border string (keep, repeat at end) */
29 static char emptydata[MAXWIDTH+1]; /* empty data, to copy then insert data */
30 /*--------------------------------------------------------------------------*/
31 void plottr(double xx, const PROBELIST& plotlist) /* plot a data point, */
33 if (active) {
34 int ii = 0;
35 double lo[2] = {0.};
36 double hi[2] = {0.};
37 double val[2] = {0.};
39 for (PROBELIST::const_iterator
40 i = plotlist.begin();
41 i != plotlist.end();
42 ++i) {
43 val[ii] = (*i)->value();
44 if ((*i)->range() != 0.) {
45 lo[ii] = (*i)->lo();
46 hi[ii] = (*i)->hi();
47 }else{
48 lo[ii] = -5.;
49 hi[ii] = 5.;
51 ++ii;
52 if (ii >= 2) {
53 break;
56 if (ii <= 1) {
57 val[1] = NOT_VALID;
59 plotarg(xx, val[0], val[1],
60 xstart, lo[0], lo[1],
61 xstop, hi[0], hi[1]);
64 /*--------------------------------------------------------------------------*/
65 /* plopen: begin the plot. any type
67 int plopen(double start, double stop, const PROBELIST& plotlist)
69 if (start == stop) {
70 IO::plotout = OMSTREAM();
72 if (!IO::plotout.any()) {
73 plclear();
74 return false;
76 xstart = start;
77 xstop = stop;
78 plhead(plotlist);
79 assert(active == false);
80 active = true;
81 return true;
83 /*--------------------------------------------------------------------------*/
84 /* plclose: finish up the plot (any type)
86 void plclose(void)
88 if (!active) {
89 return;
91 plborder();
92 active = false;
93 IO::plotout = OMSTREAM();
95 /*--------------------------------------------------------------------------*/
96 /* plclear: clear graphics mode
98 void plclear(void)
100 if (active) {
101 untested();
103 active = false;
105 /*--------------------------------------------------------------------------*/
106 /* plborder: draw the border -- Ascii graphics
108 static void plborder(void)
110 IO::plotout.tab(INDENT) << border << '\n';
112 /*--------------------------------------------------------------------------*/
113 /* calibrate: calibrate the y axis. ascii plot.
115 static void calibrate(const PROBE& prb)
117 static char nums[20]; /* this label string */
118 static char highs[20]; /* the last label string */
119 int cal; /* char position within line */
120 int stop; /* location of last label, stop printing */
121 int filled; /* how far (characters) have been printed */
122 int numsize; /* number of characters in this label */
123 int start; /* starting position of this label */
124 double markno; /* loop counter */
126 double hi, lo;
127 if (prb.range() == 0) {
128 hi = 5;
129 lo = -5;
130 }else{
131 hi = prb.hi();
132 lo = prb.lo();
134 double range = hi - lo;
136 strcpy(highs, ftos(hi, 0, 5, IO::formaat));
137 highs[8] = '\0'; /* trim to 8 chrs */
138 /* *strchr(&highs[2],' ') = '\0'; */ /* make the top label, and save */
139 stop = OUTWIDTH - static_cast<int>(strlen(highs)) - 1; /* space for it. */
141 IO::plotout << prb.label();
142 range = hi - lo;
143 filled = 0;
144 for (markno = 0.; markno < OPT::ydivisions; markno++) {
145 double number = lo + range * markno/OPT::ydivisions ;
146 if (std::abs(number) < std::abs(range)/(10.*CONSSCALE)) {
147 number = 0.;
148 } /* label to put on this div. */
149 strcpy(nums, ftos(number, 0, 5, IO::formaat));
150 nums[8] = '\0'; /* trim to 8 chrs */
151 numsize = static_cast<int>(strlen(nums)); /* center it over the mark */
152 cal = round_to_int(INDENT + CONSSCALE * (markno/OPT::ydivisions));
153 start = cal - (numsize+1)/2;
154 if (start > filled && start+numsize < stop) {
155 IO::plotout.tab(start) << nums; /* if it fits, print it */
156 filled = start + numsize ;
157 }else{untested();
160 IO::plotout.tab(stop) << highs << '\n'; /* print the last calibration */
162 /*--------------------------------------------------------------------------*/
163 static int round_to_int(double x)
165 return static_cast<int>(floor(x+.5));
167 /*--------------------------------------------------------------------------*/
168 /* plhead: begin ascii graphics
169 * print opening border, calibrations, etc.
171 static void plhead(const PROBELIST& plotlist)
173 for (PROBELIST::const_iterator
174 i = plotlist.begin();
175 i != plotlist.end();
176 ++i) {
177 calibrate(**i);
179 for (int ii = 0; ii < CONSSCALE; ii++) { /* build strings */
180 border[ii] = '-';
181 emptydata[ii] = ' ';
183 double incr = static_cast<double>(CONSSCALE) / OPT::ydivisions;
184 for (double
185 place = 0.;
186 place < static_cast<double>(CONSSCALE);
187 place += incr) {
188 border[round_to_int(place)] = '+';
189 emptydata[round_to_int(place)] = '.'; /* tics in emptydata */
191 border[CONSSCALE] = '+'; /* fix ends of the strings */
192 border[CONSSCALE+1] = '\0';
193 emptydata[CONSSCALE] = emptydata[0] = '|';
194 emptydata[CONSSCALE+1] = '\0';
196 plborder(); /* print the border */
198 /*--------------------------------------------------------------------------*/
199 /* point: return coordinate to plot in pixel #
201 static int point(
202 double yy, /* raw data */
203 double lo,
204 double hi, /* limits: both ends of the plot */
205 int scale, /* length of scale in pixels */
206 int offset, /* pixel offset of start of plot area */
207 int linswp) /* flag: linear scale (else log scale) */
209 int place;
211 if (linswp) {
212 place = round_to_int( scale*(yy-lo)/(hi-lo));
213 }else{untested();
214 place = round_to_int( scale*(log(yy/lo))/(log(hi/lo)));
217 if (place < 0) {
218 place = 0;
220 if (place > scale) {itested();
221 place = scale;
223 return place + offset;
225 /*--------------------------------------------------------------------------*/
226 /* plotarg: plot all 2 selected probes at one time, freq, etc. point.
228 /*ARGSUSED*/
229 static void plotarg(
230 double xx, /* values */
231 double yy,
232 double zz,
233 double , /* lower limits */
234 double ylo,
235 double zlo,
236 double , /* upper limits */
237 double yhi,
238 double zhi)
240 char adata[MAXWIDTH+1]; /* actual data. copy emptydata, insert */
241 char *xxs; /* string representation of xx */
242 memcpy(adata, emptydata, MAXWIDTH); /* copy prototype */
243 xxs = ftos( xx, 11, 5, IO::formaat );
244 if (zz != NOT_VALID) {
245 adata[point(zz,zlo,zhi,CONSSCALE,0,1)] = '+';/* zap data into string */
247 adata[point(yy,ylo,yhi,CONSSCALE,0,1)] = '*';
248 IO::plotout.form( "%-8.8s%s", xxs, adata );
249 IO::plotout << '\n';
251 /*--------------------------------------------------------------------------*/
252 /*--------------------------------------------------------------------------*/
253 // vim:ts=8:sw=2:noet: