1 /*
2 * $Id: oagrid.c,v 1.4 2002/07/06 08:51:42 isizaka Exp isizaka $
3 *
4 * This file is part of "Ngraph for X11".
5 *
6 * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7 *
8 * "Ngraph for X11" is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * "Ngraph for X11" is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 *
22 */
23
24 /**
25 *
26 * $Log: oagrid.c,v $
27 * Revision 1.4 2002/07/06 08:51:42 isizaka
28 * change to GPL.
29 *
30 * Revision 1.3 2001/03/23 12:15:31 isizaka
31 * for 6.3.13
32 *
33 * Revision 1.2 1999/04/15 12:15:27 isizaka
34 * for release 6.03.01
35 *
36 * Revision 1.1 1999/03/17 13:46:09 isizaka
37 * Initial revision
38 *
39 *
40 **/
41
42 #include <math.h>
43 #include <string.h>
44 #include <stdio.h>
45 #include "ngraph.h"
46 #include "object.h"
47 #include "mathfn.h"
48 #include "gra.h"
49 #include "axis.h"
50 #include "oroot.h"
51 #include "odraw.h"
52
53 #define NAME "axisgrid"
54 #define PARENT "draw"
55 #define VERSION "1.00.00"
56 #define TRUE 1
57 #define FALSE 0
58
59 #define ERRNUM 3
60
61 #define ERRNOAXISINST 100
62 #define ERRMINMAX 101
63 #define ERRAXISDIR 102
64
65 char *agriderrorlist[ERRNUM]={
66 "no instance for axis",
67 "illegal axis min/max.",
68 "illegal axis direction.",
69 };
70
agridinit(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)71 int agridinit(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
72 {
73 int wid1,wid2,wid3,dot;
74 int r,g,b,br,bg,bb;
75 struct narray *style1;
76
77 if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
78 wid1=5;
79 wid2=10;
80 wid3=20;
81 r=0;
82 g=255;
83 b=255;
84 br=255;
85 bg=255;
86 bb=255;
87 style1=arraynew(sizeof(int));
88 dot=150;
89 arrayadd(style1,&dot);
90 arrayadd(style1,&dot);
91 if (_putobj(obj,"width1",inst,&wid1)) return 1;
92 if (_putobj(obj,"width2",inst,&wid2)) return 1;
93 if (_putobj(obj,"width3",inst,&wid3)) return 1;
94 if (_putobj(obj,"style1",inst,style1)) return 1;
95 if (_putobj(obj,"R",inst,&r)) return 1;
96 if (_putobj(obj,"G",inst,&g)) return 1;
97 if (_putobj(obj,"B",inst,&b)) return 1;
98 if (_putobj(obj,"BR",inst,&br)) return 1;
99 if (_putobj(obj,"BG",inst,&bg)) return 1;
100 if (_putobj(obj,"BB",inst,&bb)) return 1;
101 return 0;
102 }
103
104
agriddone(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)105 int agriddone(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
106 {
107 if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
108 return 0;
109 }
110
agriddraw(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)111 int agriddraw(struct objlist *obj,char *inst,char *rval,int argc,char **argv)
112 {
113 int GC;
114 int fr,fg,fb,br,bg,bb,lm,tm,w,h;
115 char *axisx,*axisy;
116 int wid1,wid2,wid3,wid;
117 struct narray *st1,*st2,*st3;
118 int snum,*sdata,snum1,snum2,snum3,*sdata1,*sdata2,*sdata3;
119 struct narray iarray;
120 struct objlist *aobj;
121 int anum,id;
122 char *inst1;
123 int axposx,axposy,ayposx,ayposy,axdir,aydir,dirx,diry,axlen,aylen;
124 double axmin,axmax,aymin,aymax,axinc,ayinc,dir;
125 int axdiv,aydiv,axtype,aytype;
126 struct axislocal alocal;
127 int rcode,gx0,gy0,gx1,gy1,x0,y0,x1,y1;
128 double po,minx,miny,maxx,maxy;
129 int clip,zoom,back;
130 char *raxis;
131
132 if (_exeparent(obj,(char *)argv[1],inst,rval,argc,argv)) return 1;
133 _getobj(obj,"GC",inst,&GC);
134 if (GC<0) return 0;
135 _getobj(obj,"R",inst,&fr);
136 _getobj(obj,"G",inst,&fg);
137 _getobj(obj,"B",inst,&fb);
138 _getobj(obj,"axis_x",inst,&axisx);
139 _getobj(obj,"axis_y",inst,&axisy);
140 _getobj(obj,"width1",inst,&wid1);
141 _getobj(obj,"style1",inst,&st1);
142 _getobj(obj,"width2",inst,&wid2);
143 _getobj(obj,"style2",inst,&st2);
144 _getobj(obj,"width3",inst,&wid3);
145 _getobj(obj,"style3",inst,&st3);
146 _getobj(obj,"clip",inst,&clip);
147 _getobj(obj,"background",inst,&back);
148 _getobj(obj,"BR",inst,&br);
149 _getobj(obj,"BG",inst,&bg);
150 _getobj(obj,"BB",inst,&bb);
151 snum1=arraynum(st1);
152 sdata1=arraydata(st1);
153 snum2=arraynum(st2);
154 sdata2=arraydata(st2);
155 snum3=arraynum(st3);
156 sdata3=arraydata(st3);
157
158 if (axisx==NULL) {
159 return 0;
160 } else {
161 arrayinit(&iarray,sizeof(int));
162 if (getobjilist(axisx,&aobj,&iarray,FALSE,NULL)) return 1;
163 anum=arraynum(&iarray);
164 if (anum<1) {
165 arraydel(&iarray);
166 error2(obj,ERRNOAXISINST,axisx);
167 return 1;
168 }
169 id=*(int *)arraylast(&iarray);
170 arraydel(&iarray);
171 if ((inst1=getobjinst(aobj,id))==NULL) return 1;
172 if (_getobj(aobj,"x",inst1,&axposx)) return 1;
173 if (_getobj(aobj,"y",inst1,&axposy)) return 1;
174 if (_getobj(aobj,"length",inst1,&axlen)) return 1;
175 if (_getobj(aobj,"direction",inst1,&dirx)) return 1;
176 if (_getobj(aobj,"min",inst1,&axmin)) return 1;
177 if (_getobj(aobj,"max",inst1,&axmax)) return 1;
178 if (_getobj(aobj,"inc",inst1,&axinc)) return 1;
179 if (_getobj(aobj,"div",inst1,&axdiv)) return 1;
180 if (_getobj(aobj,"type",inst1,&axtype)) return 1;
181 if ((axmin==0) && (axmax==0) && (axinc==0)) {
182 if (_getobj(aobj,"reference",inst1,&raxis)) return 1;
183 if (raxis!=NULL) {
184 arrayinit(&iarray,sizeof(int));
185 if (!getobjilist(raxis,&aobj,&iarray,FALSE,NULL)) {
186 anum=arraynum(&iarray);
187 if (anum>0) {
188 id=*(int *)arraylast(&iarray);
189 arraydel(&iarray);
190 if ((anum>0) && ((inst1=getobjinst(aobj,id))!=NULL)) {
191 _getobj(aobj,"min",inst1,&axmin);
192 _getobj(aobj,"max",inst1,&axmax);
193 _getobj(aobj,"inc",inst1,&axinc);
194 _getobj(aobj,"div",inst1,&axdiv);
195 _getobj(aobj,"type",inst1,&axtype);
196 }
197 }
198 }
199 }
200 }
201 if ((dirx%9000)!=0) {
202 error(obj,ERRAXISDIR);
203 return 1;
204 }
205 axdir=dirx/9000;
206 if (axmin!=axmax) {
207 if (axtype==1) {
208 minx=log10(axmin);
209 maxx=log10(axmax);
210 } else if (axtype==2) {
211 minx=1/axmin;
212 maxx=1/axmax;
213 } else {
214 minx=axmin;
215 maxx=axmax;
216 }
217 }
218 }
219 if (axisy==NULL) {
220 return 0;
221 } else {
222 arrayinit(&iarray,sizeof(int));
223 if (getobjilist(axisy,&aobj,&iarray,FALSE,NULL)) return 1;
224 anum=arraynum(&iarray);
225 if (anum<1) {
226 arraydel(&iarray);
227 error2(obj,ERRNOAXISINST,axisy);
228 return 1;
229 }
230 id=*(int *)arraylast(&iarray);
231 arraydel(&iarray);
232 if ((inst1=getobjinst(aobj,id))==NULL) return 1;
233 if (_getobj(aobj,"x",inst1,&ayposx)) return 1;
234 if (_getobj(aobj,"y",inst1,&ayposy)) return 1;
235 if (_getobj(aobj,"length",inst1,&aylen)) return 1;
236 if (_getobj(aobj,"direction",inst1,&diry)) return 1;
237 if (_getobj(aobj,"min",inst1,&aymin)) return 1;
238 if (_getobj(aobj,"max",inst1,&aymax)) return 1;
239 if (_getobj(aobj,"inc",inst1,&ayinc)) return 1;
240 if (_getobj(aobj,"div",inst1,&aydiv)) return 1;
241 if (_getobj(aobj,"type",inst1,&aytype)) return 1;
242 if ((aymin==0) && (aymax==0) && (ayinc==0)) {
243 if (_getobj(aobj,"reference",inst1,&raxis)) return 1;
244 if (raxis!=NULL) {
245 arrayinit(&iarray,sizeof(int));
246 if (!getobjilist(raxis,&aobj,&iarray,FALSE,NULL)) {
247 anum=arraynum(&iarray);
248 if (anum>0) {
249 id=*(int *)arraylast(&iarray);
250 arraydel(&iarray);
251 if ((anum>0) && ((inst1=getobjinst(aobj,id))!=NULL)) {
252 _getobj(aobj,"min",inst1,&aymin);
253 _getobj(aobj,"max",inst1,&aymax);
254 _getobj(aobj,"inc",inst1,&ayinc);
255 _getobj(aobj,"div",inst1,&aydiv);
256 _getobj(aobj,"type",inst1,&aytype);
257 }
258 }
259 }
260 }
261 }
262 if ((diry%9000)!=0) {
263 error(obj,ERRAXISDIR);
264 return 1;
265 }
266 aydir=diry/9000;
267 if (aymin!=aymax) {
268 if (aytype==1) {
269 miny=log10(aymin);
270 maxy=log10(aymax);
271 } else if (aytype==2) {
272 miny=1/aymin;
273 maxy=1/aymax;
274 } else {
275 miny=aymin;
276 maxy=aymax;
277 }
278 }
279 }
280 if (((axdir+aydir)%2)==0) {
281 error(obj,ERRAXISDIR);
282 return 1;
283 }
284
285 GRAregion(GC,&lm,&tm,&w,&h,&zoom);
286 GRAview(GC,0,0,w*10000.0/zoom,h*10000.0/zoom,clip);
287 if (back) {
288 GRAcolor(GC,br,bg,bb);
289 dir=dirx/18000.0*MPI;
290 gx0=axposx;
291 gx1=axposx;
292 x1=axposx+nround(axlen*cos(dir));
293 if (x1<gx0) gx0=x1;
294 if (x1>gx1) gx1=x1;
295 gy0=axposy;
296 gy1=axposy;
297 y1=axposy-nround(axlen*sin(dir));
298 if (y1<gy0) gy0=y1;
299 if (y1>gy1) gy1=y1;
300 dir=diry/18000.0*MPI;
301 x1=ayposx;
302 if (x1<gx0) gx0=x1;
303 if (x1>gx1) gx1=x1;
304 x1=ayposx+nround(aylen*cos(dir));
305 if (x1<gx0) gx0=x1;
306 if (x1>gx1) gx1=x1;
307 y1=ayposy;
308 if (y1<gy0) gy0=y1;
309 if (y1>gy1) gy1=y1;
310 y1=ayposy-nround(aylen*sin(dir));
311 if (y1<gy0) gy0=y1;
312 if (y1>gy1) gy1=y1;
313 GRArectangle(GC,gx0,gy0,gx1,gy1,1);
314 }
315 if ((axmin==axmax) || (aymin==aymax)) goto exit;
316 GRAcolor(GC,fr,fg,fb);
317
318 if (getaxispositionini(&alocal,axtype,axmin,axmax,axinc,axdiv,TRUE)!=0) {
319 error(obj,ERRMINMAX);
320 goto exit;
321 }
322 while ((rcode=getaxisposition(&alocal,&po))!=-2) {
323 if (rcode>=1) {
324 if (rcode==1) {
325 snum=snum1;
326 sdata=sdata1;
327 wid=wid1;
328 } else if (rcode==2) {
329 snum=snum2;
330 sdata=sdata2;
331 wid=wid2;
332 } else {
333 snum=snum3;
334 sdata=sdata3;
335 wid=wid3;
336 }
337 if (wid!=0) {
338 GRAlinestyle(GC,snum,sdata,wid,0,0,1000);
339 if (axdir==0) gx0=axposx+(po-minx)*axlen/(maxx-minx);
340 else if (axdir==1) gy0=axposy-(po-minx)*axlen/(maxx-minx);
341 else if (axdir==2) gx0=axposx-(po-minx)*axlen/(maxx-minx);
342 else gy0=axposy+(po-minx)*axlen/(maxx-minx);
343 if (aydir==0) {
344 x0=ayposx;
345 y0=gy0;
346 x1=ayposx+aylen;
347 y1=gy0;
348 } else if (aydir==1) {
349 x0=gx0;
350 y0=ayposy;
351 x1=gx0;
352 y1=ayposy-aylen;
353 } else if (aydir==2) {
354 x0=ayposx;
355 y0=gy0;
356 x1=ayposx-aylen;
357 y1=gy0;
358 } else {
359 x0=ayposx;
360 y0=gy0;
361 x1=ayposx-aylen;
362 y1=gy0;
363 }
364 GRAline(GC,x0,y0,x1,y1);
365 }
366 }
367 }
368 if (getaxispositionini(&alocal,aytype,aymin,aymax,ayinc,aydiv,TRUE)!=0) {
369 error(obj,ERRMINMAX);
370 goto exit;
371 }
372 while ((rcode=getaxisposition(&alocal,&po))!=-2) {
373 if (rcode>=1) {
374 if (rcode==1) {
375 snum=snum1;
376 sdata=sdata1;
377 wid=wid1;
378 } else if (rcode==2) {
379 snum=snum2;
380 sdata=sdata2;
381 wid=wid2;
382 } else {
383 snum=snum3;
384 sdata=sdata3;
385 wid=wid3;
386 }
387 if (wid!=0) {
388 GRAlinestyle(GC,snum,sdata,wid,0,0,1000);
389 if (aydir==0) gx0=ayposx+(po-miny)*aylen/(maxy-miny);
390 else if (aydir==1) gy0=ayposy-(po-miny)*aylen/(maxy-miny);
391 else if (aydir==2) gx0=ayposx-(po-miny)*aylen/(maxy-miny);
392 else gy0=ayposy+(po-miny)*aylen/(maxy-miny);
393 if (axdir==0) {
394 x0=axposx;
395 y0=gy0;
396 x1=axposx+axlen;
397 y1=gy0;
398 } else if (axdir==1) {
399 x0=gx0;
400 y0=axposy;
401 x1=gx0;
402 y1=axposy-axlen;
403 } else if (axdir==2) {
404 x0=axposx;
405 y0=gy0;
406 x1=axposx-axlen;
407 y1=gy0;
408 } else {
409 x0=axposx;
410 y0=gy0;
411 x1=axposx-axlen;
412 y1=gy0;
413 }
414 GRAline(GC,x0,y0,x1,y1);
415 }
416 }
417 }
418 exit:
419 GRAaddlist(GC,obj,inst,(char *)argv[0],(char *)argv[1]);
420 return 0;
421 }
422
agridtight(struct objlist * obj,char * inst,char * rval,int argc,char ** argv)423 int agridtight(struct objlist *obj,char *inst,char *rval,
424 int argc,char **argv)
425 {
426 char *axis,*axis2;
427 struct narray iarray;
428 int anum,id,oid;
429 struct objlist *aobj;
430
431 if ((!_getobj(obj,"axis_x",inst,&axis)) && (axis!=NULL)) {
432 arrayinit(&iarray,sizeof(int));
433 if (!getobjilist(axis,&aobj,&iarray,FALSE,NULL)) {
434 anum=arraynum(&iarray);
435 if (anum>0) {
436 id=*(int *)arraylast(&iarray);
437 if (getobj(aobj,"oid",id,0,NULL,&oid)!=-1) {
438 if ((axis2=(char *)memalloc(strlen(chkobjectname(aobj))+10))!=NULL) {
439 sprintf(axis2,"%s:^%d",chkobjectname(aobj),oid);
440 _putobj(obj,"axis_x",inst,axis2);
441 memfree(axis);
442 }
443 }
444 }
445 }
446 arraydel(&iarray);
447 }
448 if ((!_getobj(obj,"axis_y",inst,&axis)) && (axis!=NULL)) {
449 arrayinit(&iarray,sizeof(int));
450 if (!getobjilist(axis,&aobj,&iarray,FALSE,NULL)) {
451 anum=arraynum(&iarray);
452 if (anum>0) {
453 id=*(int *)arraylast(&iarray);
454 if (getobj(aobj,"oid",id,0,NULL,&oid)!=-1) {
455 if ((axis2=(char *)memalloc(strlen(chkobjectname(aobj))+10))!=NULL) {
456 sprintf(axis2,"%s:^%d",chkobjectname(aobj),oid);
457 _putobj(obj,"axis_y",inst,axis2);
458 memfree(axis);
459 }
460 }
461 }
462 }
463 arraydel(&iarray);
464 }
465 return 0;
466 }
467
468 #define TBLNUM 17
469
470 struct objtable agrid[TBLNUM] = {
471 {"init",NVFUNC,NEXEC,agridinit,NULL,0},
472 {"done",NVFUNC,NEXEC,agriddone,NULL,0},
473 {"next",NPOINTER,0,NULL,NULL,0},
474 {"axis_x",NOBJ,NREAD|NWRITE,NULL,NULL,0},
475 {"axis_y",NOBJ,NREAD|NWRITE,NULL,NULL,0},
476 {"width1",NINT,NREAD|NWRITE,oputabs,NULL,0},
477 {"style1",NIARRAY,NREAD|NWRITE,NULL,NULL,0},
478 {"width2",NINT,NREAD|NWRITE,oputabs,NULL,0},
479 {"style2",NIARRAY,NREAD|NWRITE,NULL,NULL,0},
480 {"width3",NINT,NREAD|NWRITE,oputabs,NULL,0},
481 {"style3",NIARRAY,NREAD|NWRITE,NULL,NULL,0},
482 {"background",NBOOL,NREAD|NWRITE,NULL,NULL,0},
483 {"BR",NINT,NREAD|NWRITE,NULL,NULL,0},
484 {"BG",NINT,NREAD|NWRITE,NULL,NULL,0},
485 {"BB",NINT,NREAD|NWRITE,NULL,NULL,0},
486 {"draw",NVFUNC,NREAD|NEXEC,agriddraw,"i",0},
487 {"tight",NVFUNC,NREAD|NEXEC,agridtight,NULL,0},
488 };
489
addagrid()490 void *addagrid()
491 {
492 return addobject(NAME,NULL,PARENT,VERSION,TBLNUM,agrid,ERRNUM,agriderrorlist,NULL,NULL);
493 }
494