/* @(#)ag_orax.c 17.1.1.1 (ES0-DMD) 01/25/02 17:33:32 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /* @(#)ag_orax.c 17.1.1.1 (OAA-ASTRONET) 01/25/02 17:33:32 */ /* * HEADER : ag_orax.c - Vers 3.6.003 - Sep 1993 - L. Fini, OAA * - Vers 3.6.002 - Apr 1992 - L. Fini, OAA * - Vers 3.6.001 - Apr 1991 - L. Fini, OAA */ #include #include #define READ_FROM_BOT_C (-0.034899) #define READ_FROM_BOT_S (-0.993908) /*****************************************************************************/ /*++ AG_ORAX (User callable) */ /* AG_ORAX */ /* This module draws an axis of given orientation. */ /* The routine AG_ORAX allows the drawing of an axis with arbitrary */ /* orientation angle. The axis scales and quotes are defined independently */ /* of the current graphic status. */ /* To draw horizontal or vertical axes with a greater detail of specifica- */ /* tion the AG_AXIS() routine can be used instead. */ void AG_ORAX(flags,ends,data,form,label) int flags; /* Specification flags. The inclusive or of */ /* the following values: */ /* 1 - Draw ticks below the axis (Default is */ /* above). */ /* Quotes are drawn on the opposite side */ /* of the axis */ /* 2 - Draw tiks with specified angle (see */ /* data[6]). Default is to make tiks */ /* perpendicular to the axis. */ /* Setting flag 1 above, will add 180 */ /* degrees to the specified angle; i.e. */ /* with the same angle value tiks are */ /* drawn in the opposite direction when */ /* flag 1 is set. */ /* 4 - Draw quotes parallel to the axis. The */ /* default is to draw quotes always */ /* horizontally. */ float ends[4]; /* Axis starting and ending points: */ /* (ends[0],ends[1]) = (xstart,ystart) */ /* (ends[2],ends[3]) = (xend,yend) */ /* Values are referred to the currently active */ /* coordinate system */ float data[7]; /* Array of specifications, with the following */ /* meaning: (N.B.: array base is 0 for C and */ /* 1 for Fortran !!) */ /* The following values are independent on the */ /* active coordinate system. */ /* [0] Axis starting point coordinate */ /* [1] Axis ending point coordinate. */ /* N.B.: data[0] < data[1] */ /* [2] Divisions (ticks) starting coordinate. */ /* This may differ from the axis starting */ /* coordinate if the latter is not at an */ /* even multiple of the division step. */ /* [3] Divisions (ticks) ending coordinate. */ /* This may differ from the axis ending */ /* coordinate if the latter is not at an */ /* even multiple of the division step. */ /* N.B.: data[2] < data[3] */ /* [4] Step distance between major ticks or */ /* grid lines. If <= 0.0 no ticks or grid*/ /* lines will be drawn. */ /* If the logarithmic option is selected */ /* it is a multiplicative factor. */ /* [5] Step distance between minor ticks or */ /* If <= 0.0 no minor ticks will be drawn.*/ /* If the logarithmic option is selected */ /* it is a multiplicative factor. */ /* [6] Tiks drawing angle. This value has */ /* effect only if flag 2 is set (see */ /* above). The angle must be given in the */ /* proper units (see: AG_SSET, items */ /* DEGREES and RADIANS) and with respect */ /* to the currently defined coordinate */ /* system, independently on the actual */ /* aspect ratio of the vieport. E.g. while*/ /* in user mode with a window defined as */ /* AG_WDEF(0.,10.,0.,10) specifying an */ /* angle of 45 degrees will result in tik */ /* marks parallel to the diagonal of the */ /* window. To obtain the same result with */ /* a window defined as: */ /* AG_WDEF(0.,10.,0.,1) will require to */ /* specify an angle of 5.71 degrees (it */ /* corresponds to atan(1/10)) */ char *form; /* Format specification to draw quotes */ /* The string may contain some standard C */ /* format specifications PLUS a set of special */ /* ones as listed below (standard specifica- */ /* tion are marked with (C) and special with */ /* (S)) */ /* If the string has not the '%' as first */ /* character quotes are not drawn */ /* %[w.p]d (C) : Decimal integer */ /* %[w.p]f (C) : Floating point */ /* %[w.p]e (C) : Exponential format */ /* w=width, p=precision */ /* %g (S) : as the %f above, but strips */ /* all trailing zeroes and deci-*/ /* mal point (not the same as */ /* the C standard %g format!) */ /* %p (S) : Writes only the power of 10 */ /* %x (S) : Writes only the power of e */ /* %au (S) : Degrees */ /* %aum (S) : Degrees minutes */ /* %aums (S) : Degrees minutes seconds */ /* %ams (S) : minutes seconds */ /* %amss (S) : minutes seconds fraction */ /* %hu (S) : Hours */ /* %hum (S) : Hours minutes */ /* %hums (S) : Hours minutes seconds */ /* %hms (S) : minutes seconds */ /* %hmss (S) : minutes seconds fraction */ /* NOTE: Add more s' to the end of the format */ /* string to get more fraction digits */ char *label; /* String to be drawn as label. */ /* If the string is empty, obviously no label */ /* is drawn. */ /* Note: quotes and label are both drawn in the*/ /* current setting of character strings */ /* (see AG_SSET for details on how to set*/ /* various items affecting how characters*/ /* are drawn), and with the same char- */ /* acter size. */ /* You can modify the way the label is */ /* drawn by means of the standard AGL */ /* metacharacter sequences (see AG_GTXT) */ /*--*/ { static char *modnam = "ORAX"; static char *Mjtick = "~0\36"; /* Major tick character code */ static char *Mntick = "~0\37"; /* Minor tick character code */ float Nends[4]; float rx[3],ry[3]; float x_vect[2], y_vect[2]; double Mjstep,Mnstep; float ratio; float AngFc; int DoTiks,DoQuotes; int Qcenter; int mmode; int gmode; double nchar; double AxAngle,TkAngle,QtAngle; double xstart,ystart; double xmj,ymj; double xmn,ymn; double cosb,sinb; char aux_str[60]; char *Mjt; AG_DMSG(modnam,(char *)0); AGL_push(modnam); AG_VU2N(ends[0],ends[1],&Nends[0],&Nends[1]); AG_VU2N(ends[2],ends[3],&Nends[2],&Nends[3]); AG_IGET("mfode",&mmode); AG_IGET("mode",&gmode); AG_RGET("aspect",&ratio); AG_RGET("angfct",&AngFc); AxAngle=atan2((double)((Nends[3]-Nends[1])*ratio), (double)(Nends[2]-Nends[0])); if(!(flags&0x02)) TkAngle = AxAngle; else { float wnd[4]; double sina,cosa; TkAngle = data[6]*AngFc; if(gmode>0) { sina=sin(TkAngle); cosa=cos(TkAngle); AG_RGET("wndl",wnd); AG_RGET("clpasp",&ratio); sina *= (wnd[1]-wnd[0])*ratio; cosa *= (wnd[3]-wnd[2]); TkAngle = atan2(sina,cosa) - AG_PI05 ; } } Mjstep=(data[4]>0.0) ? data[4] : 0.0; Mnstep=data[5]; AGLsset("normal",mmode); if(flags&0x01) { AxAngle -= AG_PI; TkAngle -= AG_PI; } cosb = cos(AxAngle); sinb = sin(AxAngle); x_vect[0]=Nends[0]; x_vect[1]=Nends[2]; y_vect[0]=Nends[1]; y_vect[1]=Nends[3]; AG_GPLL(x_vect,y_vect,2); /* Draw the axis */ Mjstep=data[4]; Mnstep=data[5]; if(Mnstep0.0) { if(Mjstep==0.0) { /* This is the case when major step */ /* is 0.0 and minor step > 0.0 */ Mjstep=Mnstep; /* whe want small ticks */ Mjt=Mntick; /* where big ones would be */ DoQuotes=FALSE; /* But without quotes */ } } else Mnstep=0.0; if(DoTiks||DoQuotes) { double ax_lng; double x_rat, y_rat; ax_lng = data[1]-data[0]; x_rat = (Nends[2]-Nends[0])/ax_lng; y_rat = (Nends[3]-Nends[1])/ax_lng; xstart=Nends[0]+ x_rat*(data[2]-data[0]); ystart=Nends[1]+ y_rat*(data[2]-data[0]); xmj = x_rat*data[4]; ymj = y_rat*data[4]; xmn = x_rat*data[5]; ymn = y_rat*data[5]; } if(DoTiks) { double quote; double stop; double xp,yp; sprintf(aux_str,"changle=%f",TkAngle/AngFc); AGLsset(aux_str,mmode); if(Mjstep>0.0) Mjt=Mjtick; stop=MIN(data[2],data[0])-(Mnstep*0.001); quote=data[2]; xp=xstart; yp=ystart; while(Mnstep>0.0) { /* Draw minor ticks to the left of first */ /* major one */ /* N.B. This is an infinite loop */ /* terminated by "break" */ quote=AGLnmnt(quote,FALSE,(-Mnstep),Mjstep); if(quote0.0) { /* loop on major tiks */ double next; /* N.B. This is an infinite loop */ double xpm,ypm; /* terminated by "break" */ if(quote>AGLGuardU((double)data[3],0,Mjstep)) break; AG_GTXT(xp,yp,Mjt,1); /* Draw the tick */ next = AGLnmjt(quote,0,Mjstep); xpm=xp; ypm=yp; if(Mnstep>0.0) { /* Draw minor ticks to the right */ double curr = quote; stop=MIN(data[1],next); for(;;) { /* N.B. This is an if or an loop */ /* terminated by "break" */ quote=AGLnmnt(quote,0,Mnstep,curr); if(quote>AGLGuardU((double)stop,0,Mjstep)) break; xpm += xmn; ypm += ymn; AG_GTXT(xpm,ypm,Mntick,1); } } quote=next; xp += xmj; yp += ymj; } } if((cosb>READ_FROM_BOT_C)&&(sinb>READ_FROM_BOT_S)) { QtAngle = AxAngle; Qcenter = 20; } else { QtAngle = AxAngle-AG_PI; Qcenter = 12; } if(DoQuotes) { double quote,QAngle=QtAngle; double xp,yp; int Qc; if(flags&0x4) { float qd[2]; Qc = Qcenter; AG_RGET("chnd",qd); /* Get character normalized dims */ /* to compute quote disoplacement */ } else { QAngle = 0.0; if(cosb>0.996) /* The axis is within 5 degrees */ Qc=20; /* from horizontal quotes below */ else if(cosb<-0.996) /* The axis is within 5 degrees */ Qc=12; /* from horizontal quotes above */ else if(sinb>0.996) /* The axis is within 5 degrees */ Qc=24; /* from vertical quotes at right */ else if(sinb<-0.996) /* The axis is within 5 degrees */ Qc=16; /* from vertical quotes at leftt */ else if(cosb>0.0) if(sinb>0.0) /* The axis is in the first */ if(sinb<0.707) /* quadrant, quotes below */ Qc=21; else Qc=23; else /* The axis is in the fourth */ if(sinb<-0.707) /* quadrant, quotes below */ Qc=17; else Qc=19; else if(sinb>0.0) /* The axis is in the second */ if(sinb<0.707) /* quadrant, quotes above */ Qc=11; else Qc=9; else /* The axis is in the third */ if(sinb<-0.707) /* quadrant, quotes above */ Qc=15; else Qc=13; } sprintf(aux_str,"changle=%f",(double)QAngle/AngFc); AGLsset(aux_str,mmode); quote=data[2]; xp=xstart; yp=ystart; nchar=0; while(quotenchar) { /* string length for label */ nchar=qthlng; /* spacing is computed on */ AG_TGET(aux_str,rx,ry); /* the longest quote */ } quote = AGLnmjt(quote,0,Mjstep); xp += xmj; yp += ymj; } } if(*label!='\0') { double x0,y0; double sx; /* Compute space occupied by quotes */ if(flags&0x4) { sx = 2.0*sqrt((double)(rx[2]*rx[2])+(double)(ry[2]*ry[2])); } else { sx = fabs(rx[0]*(1.0+1.5/(double)nchar)*sinb) + fabs(ry[2]*cosb*2.0); } x0 = (Nends[2]+Nends[0])*0.5 + sinb*sx; y0 = (Nends[3]+Nends[1])*0.5 - cosb*sx; sprintf(aux_str,"changle=%f",(double)QtAngle/AngFc); AGLsset(aux_str,mmode); AG_GTXT(x0,y0,label,Qcenter); } switch(gmode) { case 1: AGLsset("user",mmode); break; case 2: AGLsset("special",mmode); break; } AGLsset("lfrg;lstyl=0",mmode); /* reset line style */ AGL_pop(); }