/* @(#)bldgra.c 17.1.1.1 (ESO-DMD) 01/25/02 17:39:33 */ /*=========================================================================== 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 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence 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 ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .IDENTIFICATION function buildgra version 2.50 860314 K. Banse ESO - Garching .KEYWORDS vector, graphics .PURPOSE compute (x,y) coordinates for given graph (shape) .ALGORITHM depending on the shape, move along its contours + record "extreme" points ---------------------------------------------------------------------- */ #include #include #define MIN(a,b) ((a)<(b))?(a):(b) #define MAX(a,b) ((a)>(b))?(a):(b) /* */ void buildgra(shape,coords,arcs,xfig,yfig,figmax,nop) char *shape; /* IN: shape of graph, [0,1] pure shape = RE, for rectangle = CI, for circle = EL, for ellipse = SL, for slit = AR, for arrow = LI, for line = CR, for cross [2] shape_option = F, fill graph else not, for RE, CI,EL, SL [2] = '1','2','3','4' for arrow direction */ int *coords; /* IN: holds necessary input params for graph dimension + meaning depends upon SHAPE for REC: the two opposite coordinate pairs of desired rectangle CIR: center coords + radius ELL: center coords + major, minor semiaxis LIN: start + end coordinates CRO: center coords + length */ float *arcs; /* IN: only for CIRCLE, ELLIPS start + end angle of arc */ int *xfig; /* OUT: array to hold x coords of created graph */ int *yfig; /* OUT: array to hold y coords of created graph */ int figmax; /* IN: max. size of `xfig' + `yfig' */ int *nop; /* OUT: no. of points used in `xfig', `yfig' */ { int beginx, endx, beginy, endy; int ix, iy, k, n, n1, n2, noc, sw; int distx, center[2]; register int nr; float radius, rconst, angle, angla, anglb, a, b, aa; double twopi = 6.28318530710000012; /* 2 * Pi */ double facto = 0.0174532925; /* Pi / 180. */ /* branch according to shape */ if ((shape[0] == 'R') && (shape[1] == 'E')) { /* construct coordinates for a rectangle */ if (shape[2] != 'F') { xfig[0] = coords[0]; /* start point */ yfig[0] = coords[1]; xfig[1] = coords[2]; /* move right... */ yfig[1] = coords[1]; xfig[2] = coords[2]; /* move up... */ yfig[2] = coords[3]; xfig[3] = coords[0]; /* move left... */ yfig[3] = coords[3]; xfig[4] = coords[0]; /* move down to start again... */ yfig[4] = coords[1]; *nop = 5; } else { if (coords[1] < coords[3]) { n1 = coords[1]; n2 = coords[3]; } else { n1 = coords[3]; n2 = coords[1]; } k = 0; sw = 0; for (nr=n1; nr<(n2+1); nr++) { xfig[k] = coords[sw]; yfig[k] = nr; xfig[k+1] = coords[2-sw]; yfig[k+1] = nr; k += 2; /* increment counter */ sw = 2 - sw; /* and switch */ } *nop = k; } } else if ((shape[0] == 'C') && (shape[1] == 'I')) { /* construct coordinates for a circle */ center[0] = coords[0]; center[1] = coords[1]; radius = coords[2]; n = CGN_NINT(radius); if (n < 1) n1 = 5 ; else if (n < 6) n1 = 5 * n; else n1 = 8 * n; noc = MIN(figmax-1,n1); /* get no. of points to draw */ rconst = twopi/noc ; angla = arcs[0]*facto; anglb = arcs[1]*facto; /* loop through points on circle */ if (shape[2] != 'F') { if (angla < 0.0) /* direct call to buildgra... */ { angle = 0.0; for (nr=0; nr anglb) break; } *nop = nr + 1; } } else { beginy = center[1] - radius; endy = center[1] + radius; xfig[0] = center[0]; yfig[0] = beginy; n = 1; sw = -900; /* start at -90. degrees */ aa = 0.1 * facto; for (nr=beginy+1; nr<=endy; nr++) { sect_2300: sw ++; if (sw > 900) break; angle = (float)sw * aa; /* move in steps of 0.1 degree */ iy = CGN_NINT(radius*sin(angle)); n1 = center[1] + iy; /* test y-value of circle */ if (n1 < nr) goto sect_2300; ix = CGN_NINT(radius*cos(angle)); xfig[n] = center[0] + ix; yfig[n++] = center[1] + iy; xfig[n] = center[0] - ix; yfig[n] = yfig[n-1]; n ++; xfig[n] = center[0] + ix; yfig[n] = yfig[n-1]; n ++; } xfig[n] = center[0]; yfig[n] = endy; *nop = n + 1; } } else if ((shape[0] == 'L') && (shape[1] == 'I')) { /* construct coordinates for straight line */ if ((shape[2] == '2') || (shape[2] == '3')) { xfig[0] = coords[0]; yfig[0] = coords[3]; xfig[1] = coords[2]; yfig[1] = coords[1]; } else { xfig[0] = coords[0]; yfig[0] = coords[1]; xfig[1] = coords[2]; yfig[1] = coords[3]; } *nop = 2; } else if ((shape[0] == 'E') && (shape[1] == 'L')) { /* construct coordinates for an ellips */ center[0] = (coords[0]+coords[2])/2; center[1] = (coords[1]+coords[3])/2; a = (coords[2]-coords[0]) * 0.5; /* get major + minor axis */ b = (coords[3]-coords[1]) * 0.5; aa = (a+b)/2; n2 = 5*CGN_NINT(aa); noc = MIN(figmax-1,n2); /* get no. of points to draw */ rconst = twopi/noc ; angla = arcs[0]*facto; anglb = arcs[1]*facto; /* loop through points on ellipse */ if (shape[2] != 'F') { noc ++; if (angla < 0.0) /* direct call to buildgra... */ { angle = 0.0; for (nr=0; nr anglb) break; } *nop = nr + 1; } } else { beginy = center[1] - CGN_NINT(b); endy = center[1] + CGN_NINT(b); xfig[0] = center[0]; yfig[0] = beginy; n = 1; sw = -900; /* start at -90. degrees */ aa = 0.1 * facto; for (nr=beginy+1; nr<=endy; nr++) { sect_4300: sw ++; if (sw > 900) break; angle = (float)sw * aa; /* move in steps of 0.1 degree */ iy = CGN_NINT(b*sin(angle)); n1 = center[1] + iy; /* test y-value of circle */ if (n1 < nr) goto sect_4300; ix = CGN_NINT(a*cos(angle)); xfig[n] = center[0] + ix; yfig[n++] = center[1] + iy; xfig[n] = center[0] - ix; yfig[n] = yfig[n-1]; n ++; xfig[n] = center[0] + ix; yfig[n] = yfig[n-1]; n ++; } xfig[n] = center[0]; yfig[n] = endy; *nop = n + 1; } } else if ((shape[0] == 'C') && (shape[1] == 'R')) { /* construct coordinates of a cross (as closed fig */ xfig[0] = coords[0]; /* start at bottom */ yfig[0] = coords[1] - coords[2]; xfig[1] = coords[0]; /* move to top... */ yfig[1] = coords[1] + coords[2]; xfig[2] = coords[0]; /* move down to center... */ yfig[2] = coords[1]; xfig[3] = coords[0] + coords[2]; /* move to right end... */ yfig[3] = coords[1]; xfig[4] = coords[0] - coords[2]; /* move to left end... */ yfig[4] = coords[1]; *nop = 5; } else if ((shape[0] == 'A') && (shape[1] == 'R')) { /* construct coordinates of an arrow */ if (shape[2] == '1') { beginx = coords[0]; beginy = coords[1]; endx = coords[2]; endy = coords[3]; } else if (shape[2] == '2') { beginx = coords[0]; beginy = coords[3]; endx = coords[2]; endy = coords[1]; } else if (shape[2] == '3') { beginx = coords[2]; beginy = coords[1]; endx = coords[0]; endy = coords[3]; } else { beginx = coords[2]; beginy = coords[3]; endx = coords[0]; endy = coords[1]; } xfig[0] = beginx; yfig[0] = beginy; xfig[1] = endx; yfig[1] = endy; ix = endx - beginx; iy = endy - beginy; a = sqrt((float)(ix*ix) + (float)(iy*iy)); /* get length of arrow */ b = a / 8.0; if (b < 2.0) b = 2.0; angle = atan2((float)iy,(float)ix); angle += (135. * facto); xfig[2] = endx + CGN_NINT(b*cos(angle)); /* move to left of top */ yfig[2] = endy + CGN_NINT(b*sin(angle)); xfig[3] = endx; /* move back to top of arrow */ yfig[3] = endy; angle += (90. * facto); xfig[4] = endx + CGN_NINT(b*cos(angle)); /* move to right of top */ yfig[4] = endy + CGN_NINT(b*sin(angle)); *nop = 5; } else if ((shape[0] == 'S') && (shape[1] == 'L')) { /* construct coordinates of a slit (as used in IUE) */ xfig[0] = coords[0]; /* start at lower left corner */ yfig[0] = coords[1]; xfig[1] = coords[2]; /* move to right corner */ yfig[1] = coords[1]; center[0] = coords[2]; center[1] = (coords[1]+coords[3])/2; radius = (coords[3]-coords[1])/2; if (shape[2] == 'F') goto sect_7500; /* handle fill option farther down */ noc = figmax-5; n1 = 10*CGN_NINT(radius); if (noc > n1) noc = n1; /* take min */ rconst = twopi/noc ; /* loop through points on circle (but draw only outer half) */ n = 2; aa = 90. * facto; for (nr=0; nr<(noc/2)+1; nr++) { angle = (nr * rconst) - aa; xfig[n] = center[0] + CGN_NINT(radius*cos(angle)); yfig[n++] = center[1] + CGN_NINT(radius*sin(angle)); } xfig[n] = coords[2]; /* make sure, we hit upper right corner */ yfig[n++] = coords[3]; xfig[n] = coords[0]; /* move to upper left corner */ yfig[n++] = coords[3]; center[0] = coords[0]; /* loop through points on circle (but draw only outer half) */ for (nr=(noc/2); nr<(noc+1); nr++) { angle = (nr * rconst) - aa; xfig[n] = center[0] + CGN_NINT(radius*cos(angle)); yfig[n++] = center[1] + CGN_NINT(radius*sin(angle)); } xfig[n] = coords[0]; /* make sure, we finish at lower left corner */ yfig[n] = coords[1]; *nop = n + 1; return; /* here for filled slit */ sect_7500: beginy = coords[1]; endy = coords[3]; n = 2; sw = -900; /* start at -90. degrees */ aa = 0.1 * facto; distx = coords[2] - coords[0]; /* size in x */ for (nr=beginy+1; nr<=endy; nr++) { sect_7800: sw ++; if (sw > 900) break; angle = (float)sw * aa; /* move in steps of 0.1 degree */ iy = CGN_NINT(radius*sin(angle)); n1 = center[1] + iy; /* test y-value of circle */ if (n1 < nr) goto sect_7800; ix = CGN_NINT(radius*cos(angle)); xfig[n] = center[0] + ix; yfig[n++] = center[1] + iy; xfig[n] = center[0] - ix -distx; /* circle on other side... */ yfig[n] = yfig[n-1]; n ++; xfig[n] = center[0] + ix; yfig[n] = yfig[n-1]; n ++; } xfig[n] = coords[0]; yfig[n++] = endy; xfig[n] = coords[2]; yfig[n] = endy; *nop = n + 1; } else if ((shape[0] == 'T') && (shape[1] == 'R')) { /* construct coordinates of a triangle */ xfig[0] = coords[0] ; yfig[0] = coords[1]; xfig[1] = coords[2] ; yfig[1] = coords[3] ; xfig[2] = coords[4] ; yfig[2] = coords[5]; xfig[3] = coords[0] ; yfig[3] = coords[1] ; *nop = 4; } return; }