1 /*
2 * Copyright (C) 1997-2005, R3vis Corporation.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18 *
19 * Original Contributor:
20 * Wes Bethel, R3vis Corporation, Marin County, California
21 * Additional Contributor(s):
22 *
23 * The OpenRM project is located at http://openrm.sourceforge.net/.
24 */
25 /*
26 * $Id: rmverrplot.c,v 1.5 2005/02/19 16:09:13 wes Exp $
27 * Version: $Name: OpenRM-1-6-0-2-RC2 $
28 * $Revision: 1.5 $
29 * $Log: rmverrplot.c,v $
30 * Revision 1.5 2005/02/19 16:09:13 wes
31 * Distro sync and consolidation.
32 *
33 * Revision 1.4 2005/01/23 17:11:02 wes
34 * Copyright updated to 2005.
35 *
36 * Revision 1.3 2004/01/17 04:09:26 wes
37 * Updated copyright line for 2004.
38 *
39 * Revision 1.2 2003/02/02 02:07:23 wes
40 * Updated copyright to 2003.
41 *
42 * Revision 1.1.1.1 2003/01/28 02:15:23 wes
43 * Manual rebuild of rm150 repository.
44 *
45 * Revision 1.6 2003/01/16 22:21:20 wes
46 * Updated all source files to reflect new organization of header files:
47 * all header files formerly located in include/rmaux, include/rmi, include/rmv
48 * are now located in include/rm.
49 *
50 * Revision 1.5 2002/04/30 19:40:00 wes
51 * Updated copyright dates.
52 *
53 * Revision 1.4 2001/03/31 17:10:08 wes
54 * v1.4.0-alpha-2 checkin.
55 *
56 * Revision 1.3 2000/08/28 01:34:30 wes
57 * No signficant changes.
58 *
59 * Revision 1.2 2000/04/20 16:17:45 wes
60 * JDB modifications: code rearrangement, additional docs.
61 *
62 * Revision 1.1 2000/04/17 00:05:23 wes
63 * Lots of documentation updates, courtesy of jdb.
64 *
65 * Revision 1.1.1.1 2000/02/28 21:29:40 wes
66 * OpenRM 1.2 Checkin
67 *
68 * Revision 1.1.1.1 2000/02/28 17:18:48 wes
69 * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
70 *
71 */
72
73 #include <rm/rm.h>
74 #include <rm/rmv.h>
75 #include "rmvprivt.h"
76
77 /*
78 * ----------------------------------------------------
79 * @Name rmvI2ErrorPlot
80 @pstart
81 RMenum rmvI2ErrorPlot (RMvertex2D (*appgridfunc)(int i),
82 float (*appu1func)(int i),
83 float (*appu2func)(int i),
84 float (*appl1func)(int i),
85 float (*appl2func)(int i),
86 float (*appdata2func)(int i),
87 RMvisMap *vmap,
88 int axis_offset_flag,
89 int npts,
90 RMenum linewidth,
91 RMenum linestyle,
92 RMnode *n)
93 @pend
94
95 @astart
96
97 RMvertex2D (*appgridfunc)(int i) - a handle to a caller-supplied
98 function that returns an RMvertex2D (x, y) corresponding to the
99 grid point (i) (input).
100
101 float (*appu1func)(int i) - a handle to caller-supplied function that
102 returns a lower bound float for the upper pair at the grid point
103 (i) (input).
104
105 float (*appu2func)(int i) - a handle to caller-supplied function that
106 returns a upper bound float for the upper pair at the grid point
107 (i) (input).
108
109 float (*appl1func)(int i) - a handle to caller-supplied function that
110 returns a lower bound float for the lower pair at the grid point
111 (i) (input).
112
113 float (*appl2func)(int i) - a handle to caller-supplied function that
114 returns a upper bound float for the lower pair at the grid point
115 (i) (input).
116
117 float (*appdata2func)(int i) - a handle to a caller-supplied function
118 that returns a scalar value for the grid point (i). This value is
119 used in conjunction with the RMvismap to compute vertex color.
120
121 RMvisMap *vmap - a handle to an RMvisMap object (input).
122
123 int axis_offset_flag - an RMenum specifying in which axis to
124 offset the glyph. Must be one of RMV_XAXIS_OFFSET,
125 RMV_YAXIS_OFFSET (input).
126
127 int npts - int specifying number of grid data points (input).
128
129 RMenum linewidth_enum - an RMenum specifying the line width. Must be
130 one of RM_LINEWIDTH_NARROW, RM_LINEWIDTH_MEDIUM,
131 RM_LINEWIDTH_HEAVY, or RM_LINEWIDTH_[1..8] (input).
132
133 RMenum linestyle_enum - an RMenum specifying the lline style. Must
134 be one of RM_LINES_SOLID, RM_LINES_DASHED, RM_LINES_DOTTED,
135 RM_LINES_DOT_DASH, or RM_LINES_DASH_DASH_DOT (input).
136
137 RMnode *n - a handle to an RMnode (modified).
138 @aend
139
140 @dstart
141
142 Creates an "error bar" plot for indicating data ranges. Pairs of
143 error bars are plotted from the four caller-supplied functions, {u1,
144 u2, l1, l2}. These functions return a data value for a given grid
145 point and indicate a pair of data ranges {[l1..l2], [u1..u2]}. The
146 secondary data function can be used with the RMvisMap to color the
147 error bars.
148
149 Upon success, RM_CHILL is returned to the caller and the error plot
150 geometry has been added to the RMnode. Otherwise, RM_WHACKED is
151 returned.
152
153 @dend
154 * ----------------------------------------------------
155 */
156 RMenum
rmvI2ErrorPlot(RMvertex2D (* appgridfunc)(int i),float (* appu1func)(int i),float (* appu2func)(int i),float (* appl1func)(int i),float (* appl2func)(int i),float (* appdata2func)(int i),RMvisMap * vmap,int axis_offset_flag,int npts,RMenum linewidth,RMenum linestyle,RMnode * n)157 rmvI2ErrorPlot (RMvertex2D (*appgridfunc)(int i),
158 float (*appu1func)(int i),
159 float (*appu2func)(int i),
160 float (*appl1func)(int i),
161 float (*appl2func)(int i),
162 float (*appdata2func)(int i),
163 RMvisMap *vmap,
164 int axis_offset_flag,
165 int npts,
166 RMenum linewidth,
167 RMenum linestyle,
168 RMnode *n)
169 {
170 int i, j = 0;
171 RMprimitive *t;
172 RMvertex2D *v;
173 RMcolor4D *c;
174
175 /* error check on functions, etc. */
176 {
177 int s1, s2, s3, s4, s5, s6, s7;
178
179 s1 = RM_ASSERT((void *)n, "rmvI2ErrorPlot error: NULL RMnode for return parameter");
180 s2 = RM_ASSERT((void *)appgridfunc, "rmvI2ErrorPlot error: NULL app grid callback");
181 s3 = RM_ASSERT((void *)appu1func, "rmvI2ErrorPlot error: NULL app u1 callback ");
182 s4 = RM_ASSERT((void *)appu2func, "rmvI2ErrorPlot error: NULL app u2 callback ");
183 s5 = RM_ASSERT((void *)appl1func, "rmvI2ErrorPlot error: NULL app l1 callback ");
184 s6 = RM_ASSERT((void *)appl2func, "rmvI2ErrorPlot error: NULL app l2 callback ");
185 s7 = RM_CHILL;
186 if (!(((vmap != NULL) && (appdata2func != NULL)) || ((vmap == NULL) && (appdata2func == NULL))))
187 s7 = RM_ASSERT((void *)NULL,"rmvI2ErrorPlot error: the vismap and secondary data callback function must BOTH be NULL or defined.");
188
189 if ((s1 == RM_WHACKED) || (s2 == RM_WHACKED) || (s3 == RM_WHACKED) || (s4 == RM_WHACKED) || (s5 == RM_WHACKED) || (s6 == RM_WHACKED) || (s7 == RM_WHACKED))
190 return(RM_WHACKED);
191 }
192
193 v = rmVertex2DNew(npts * 4);
194 t = rmPrimitiveNew(RM_LINES);
195
196 if (vmap != NULL)
197 c = rmColor4DNew(npts * 2);
198 else
199 c = NULL;
200
201 /* do the upper part */
202 for (i = 0; i < npts; i++)
203 {
204 float maxs, uppers;
205 RMvertex2D base;
206
207 base = (*appgridfunc)(i);
208 maxs = (*appu1func)(i);
209 uppers = (*appu2func)(i);
210
211 v[j] = base;
212 v[j + 1] = base;
213
214 switch (axis_offset_flag)
215 {
216 case RMV_XAXIS_OFFSET:
217 v[j].x += uppers;
218 v[j + 1].x += maxs;
219 break;
220
221 case RMV_YAXIS_OFFSET:
222 v[j].y += uppers;
223 v[j + 1].y += maxs;
224 break;
225
226 default: /* bogus axis offset enum */
227 break;
228 }
229
230 j += 2;
231
232 if (c)
233 {
234 int k;
235 float d2;
236
237 d2 = (*appdata2func)(i);
238 k = rmVismapIndexFromData(vmap, d2);
239 rmVismapGetColor4D(vmap, k, (c + i));
240 }
241 }
242
243 /* do the lower part */
244 for (i = 0; i < npts; i++)
245 {
246 float mins, lowers;
247 RMvertex2D base;
248
249 base = (*appgridfunc)(i);
250 mins = (*appl1func)(i);
251 lowers = (*appl2func)(i);
252
253 v[j] = base;
254 v[j + 1] = base;
255
256 switch (axis_offset_flag)
257 {
258 case RMV_XAXIS_OFFSET:
259 v[j].x += lowers;
260 v[j + 1].x += mins;
261 break;
262
263 case RMV_YAXIS_OFFSET:
264 v[j].y += lowers;
265 v[j + 1].y += mins;
266 break;
267
268 default: /* bogus axis offset enum */
269 break;
270 }
271
272 if (c)
273 {
274 int k;
275 float d2;
276
277 d2 = (*appdata2func)(i);
278 k = rmVismapIndexFromData(vmap, d2);
279 rmVismapGetColor4D(vmap, k, (c + i + npts));
280 }
281 j += 2;
282 }
283 rmPrimitiveSetVertex2D(t, (npts * 4), v, RM_COPY_DATA, NULL);
284
285 if (c)
286 {
287 rmPrimitiveSetColor4D(t, (npts * 2), c, RM_COPY_DATA, NULL);
288 rmColor4DDelete(c);
289 }
290 rmNodeSetLineWidth(n, linewidth);
291 rmNodeSetLineStyle(n, linestyle);
292
293 /* now, add the new primitive onto the node */
294 rmNodeAddPrimitive(n, t);
295 rmVertex2DDelete(v);
296
297 return(RM_CHILL);
298 }
299 /* EOF */
300