/* @(#)draw.c 17.1.1.1 (ESO-IPG) 01/25/02 17:39:59 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT: Copyright (c) 1994 European Southern Observatory, all rights reserved .IDENTIFIER DRAW .LANGUAGE C .AUTHOR K. Banse, ESO Garching .KEYWORDS ImageDisplay, cursor .PURPOSE a) use cursor rectangle to get the position of the two cursors on the ImageDisplay and draw the desired figure into the overlay channel b) plot contents of a 1-dim frame as y-coords into DeAnza .ALGORITHM a) exit by pressing ENTER with both cursors off. b) a frame is scaled in x and z, the scaled image is then plotted into a 512*512 byte memory board of DeAnza .INPUT/OUTPUT the following keys are used: MYACT/C/1/2 = RE, for rectangle = CI, for circle = EL, for ellips = SL, for slit = AR, for arrow = LI, for straight line = CR, for cross = AN, for interactively defined lines (DRAW/ANY) = FI for executing an ASCII file containing DRAW/.. commands = XI, for drawing an image P1/C/1/100 specs for input = name for table (a) = CURSOR for interactive input (b) = coord_string for fixed position (c) P2/C/1/1 = F for frame related coords (a,c) = S for screen coords. (a,c) for (b) only S applicable INPUTR/R/1/3 (1) rotation angle (2) start angle - only for Circle, Ellips (3) end angle - in degrees from 0 to 360 0 degrees is along positive x-axis, increasing counter clockwise P3/C/1/3 drawing option (1:1) = F, if shape should be filled or N if not, for RE,CI,EL,SL (1:2) = RU,RD,LU,LD (right-up,right-down,...) direction of arrow, for AR (1:3) = size of cross arms in screen pixels for CR DAZHOLD/I/1/1 cursor no., 0, 1 or 2 --------------------------------------------------------- for DRAW/IMAGE (XI) IN_A/C/1/60 data frame to be loaded DAZHOLD/I/3/1 split mode, = 0 for single image = 1 for 3/4 images DAZIN/I/1/1 scaling factor used, if DEFAULT(1:1) = 'N' DEFAULT/C/1/5 default flags (1) = 'Y', take scaling of image from descr. DISPLAY_DATA(1,2) = 'N', take scaling from key DAZIN (2) = 'N', take x-center and yline from key INPUTC (3) = 'Y', take cuts of image from descr. CUTS(1,2) = 'N', take cuts of image from INPUTR(1,2) (5) = 'Y', overplot on existing image else, clear channel first (6) = 'N', use fixpixel INPUTI/I/1/2 if DEFAULT(6:6).NE.'Y', (1,2) frame,screen pixel of fixpoint INPUTR/R/1/6 (1,2) cuts if DEFAULT(3) = 'N' (3) = highest possible value for y-pixels (4) = offset in y on display, in [0,QMSZY-1] (5) = intensity in [0,255] (6) optional angle .VERSION 1.00 940620 converted from DRAW.FOR R.M.van Hees 010110 last modif ------------------------------------------------------------*/ /* Define _POSIX_SOURCE to indicate that this is a POSIX program */ #define _POSIX_SOURCE 1 #include #include #include #include #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #ifndef MYABS #define MYABS(a) ((a)>0)?(a):(-(a)) #endif #ifndef PI #define PI 3.14159265358979325e0 #endif #define DEG2RAD (PI / 180.0) #define NSHAPE 9 #define MXFIG 1024 /* */ int main() { register int nn; int actvals, intens, knul, length, ncurs, nmal, npnts, stat, unit; int input_fl, rota_fl, shape_fl, coord[4], dazhld[13]; int fid, begin, m; int xfig[2 * MXFIG], yfig[2 * MXFIG]; float rdum, rotang, arcs[2], rbuff[4], cpos[4]; double ca, sa; double ddum; char ref[2], dropt[4], shape[7], keynm[16], cbuff[102], frame[102], table[102], output[82]; char *err_qual = "DRAW: unknown qualifier...", *usr_curs = "Give a second position, using the cursor"; static char *shapes[NSHAPE] = { "RE","CI","EL","SL","AR","LI","CR","AN","XI" }; static int shpcur[NSHAPE] = { 2, 2, 2, 2, 2, 2, 0, 0, 0 }; enum shapeflags { RE, CI, EL, SL, AR, LI, CR, AN, XI }; enum inputflags { KEYW, FIXP, TABL, CURS }; (void) SCSPRO("DRAW"); for (nn=0; nn<4; nn++) { cpos[nn] = 0.0; coord[nn] = 0; } arcs[0] = arcs[1] = 0.0; /* Attach ImageDisplay + get info about displayed image */ DCOPEN(1); (void) SCKRDI("AUX_MODE",9,1,&actvals,&nmal,&unit,&knul); if (nmal == 1) CONCHA_C(QDSPNO,QOVCH,1,0); /* Get split mode + addresses + memories per pixel */ (void) SCKRDI("DAZHOLD",1,13,&actvals,dazhld,&unit,&knul); if (dazhld[12] == QIMCH) (void) Cdazscr(QDSPNO,QOVCH,&SCROLX,&SCROLY); /* get shape of region */ (void) SCKGETC("MYACT",1,2,&actvals,shape); CGN_UPSTR(shape); fid = -1; if (shape[0] == 'F') { /* DRAW in a loop reading the commands from an ASCII file */ (void) SCKGETC("DRAWCOLOR",1,80,&actvals,table); fid = osaopen(table,0); if (fid < 0) { sprintf(output,"Could not open file: %s",table); SCETER(11,table); } } file_loop: if (fid > -1) { CGN_FILL(output,' ',80); nn = osaread(fid,output,80); if (nn <0) { (void) osaclose(fid); goto end_of_it; } begin = 0; length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); if ((length < 2) || (cbuff[0] == '!')) goto file_loop; m = CGN_INDEXC(cbuff,'/') + 1; if (m < 2) goto file_loop; CGN_UPSTR(cbuff); shape[0] = cbuff[m++]; shape[1] = cbuff[m]; length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); /* 1. param */ if (length < 1) goto file_loop; if (shape[0] == 'W') /* DRAW/WAIT */ { m = CGN_CNVT(cbuff,2,1,&length,rbuff,&ddum); if (m < 1) rbuff[0] = 1.; /* default to 1 sec */ length = CGN_NINT(rbuff[0]*1000.); /* units are millisecs */ OSY_SLEEP(length,0); goto file_loop; } cbuff[length++] = ' '; cbuff[length++] = '\0'; (void) SCKWRC("P1",1,cbuff,1,length,&unit); length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); /* 2. param */ if (length < 1) goto file_loop; cbuff[length++] = ' '; cbuff[length++] = '\0'; (void) SCKWRC("P2",1,cbuff,1,length,&unit); length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); /* 3. param */ if (length < 1) goto file_loop; cbuff[length++] = ' '; cbuff[length++] = '\0'; (void) SCKWRC("P3",1,cbuff,1,length,&unit); length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); /* 4. param */ if (length < 1) goto file_loop; rbuff[0] = 0.; rbuff[1] = rbuff[2] = -1.0; m = CGN_INDEXC(cbuff,','); if (m > 0) { m = CGN_CNVT(&cbuff[m+1],2,1,&unit,rbuff,&ddum); cbuff[m++] = ' '; cbuff[m++] = '\0'; (void) SCKWRC("DRAWCOLOR",1,cbuff,1,m,&unit); } else { cbuff[length++] = ' '; cbuff[length++] = '\0'; (void) SCKWRC("DRAWCOLOR",1,cbuff,1,length,&unit); } length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); /* skip 5. param */ if (length > 0) { length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); /* 6. param */ if (length > 0) { cbuff[1] = ' '; (void) SCKWRC("P6",1,cbuff,1,2,&unit); } length = CGN_EXTRSS(output,nn,' ',&begin,cbuff,80); /* 7. param */ if (length > 0) m = CGN_CNVT(cbuff,2,2,&unit,&rbuff[1],&ddum); } (void) SCKWRR("INPUTR",rbuff,1,3,&unit); } nn = 0; while ((nn < NSHAPE) && (strncmp(shape,shapes[nn],2) != 0)) nn++; if (nn == NSHAPE) SCETER(1,err_qual); /* EXIT */ ncurs = shpcur[nn]; shape_fl = nn; /* Get intensity and rotation option (+ eventual start/stop angles) */ (void) SCKGETC("DRAWCOLOR",1,4,&actvals,table); intens = tstcolor(table); (void) SCKRDR("INPUTR",1,3,&actvals,rbuff,&unit,&knul); rotang = rbuff[0]; rota_fl = (MYABS(rotang) > 0.01) ? TRUE : FALSE; if (rota_fl) { ca = cos( DEG2RAD * rotang ); sa = sin( DEG2RAD * rotang ); } arcs[0] = -1.0; if ((shape_fl > 0) && (shape_fl < 3)) /* for circle, ellips */ { if (rbuff[1] < 0) arcs[0] = -1.0; else { arcs[0] = rbuff[1]; if (rbuff[2] < 0) arcs[1] = 360.0; else arcs[1] = rbuff[2]; } } if (shape_fl == 8) /* draw/image */ DRAW_IMA(); else if (shape_fl == 7) /* draw/any */ DRAW_ANY(intens); /* Set the drawing option - filled or not, - right-up, -down, left-up, -down, - size of cross arms */ else { (void) SCKGETC("P3",1,3,&actvals,dropt); CGN_UPSTR(dropt); /* shape[0,1] = shape of figure shape[2] = F(ill) or N(ofill) (for figures which can be filled) shape[2] = direction for arrows shape[3] = '3' or '4' for circle options (center+radius or rectangle) */ switch (shape_fl) { case RE: case EL: case SL: shape[2] = dropt[0]; break; case CI: shape[3] = '4'; shape[2] = dropt[0]; rota_fl = FALSE; break; case AR: case LI: if ( strncmp( dropt, "RD", 2 ) == 0 ) shape[2] = '2'; else if ( strncmp( dropt, "LU", 2 ) == 0 ) shape[2] = '3'; else if ( strncmp( dropt, "LD", 2 ) == 0 ) shape[2] = '4'; else shape[2] = '1'; break; case CR: if ( CGN_CNVT(dropt,1,1,&length,&rdum,&ddum) <= 0 ) length = 9; break; default: SCETER(2,err_qual); break; } /* Get input option: via Keyword, Cursor, Table or Fixed coordinates */ (void) strcpy(ref,"S"); (void) SCKGETC("P6",1,1,&actvals,frame); if ( *frame == 'k' || *frame == 'K' ) { /* input from keyword */ (void) SCKGETC("P1",1,15,&actvals,keynm); input_fl = KEYW; } else { /* input explicitely */ (void) SCKGETC("P1",1,100,&actvals,frame); CGN_UPCOPY(cbuff,frame,100); if (strncmp(cbuff,"CURSOR",6) == 0) input_fl = CURS; /* center chosen via cursor */ else { (void) SCKGETC("P2",1,1,&actvals,ref); /* get coord. ref. */ if (*ref == 'f') *ref = 'F'; /* use frame (world) coords */ else if (*ref == 'p') *ref = 'P'; /* use pixel values */ nmal = CGN_INDEXC(cbuff,','); if (nmal <= 0) { CGN_FRAME(frame,2,table,0); input_fl = TABL; if (*ref == '+') *ref = 'F'; /* default for table input */ } else input_fl = FIXP; if ((*ref == 'F') || (*ref == 'P')) { /* get displayed frame */ CGN_FRAME("*",1,frame,0); nmal = CGN_INDEXC(frame,' '); if (nmal > 0) frame[nmal] = '\0'; /* truncate name */ } else { (void) strcpy(ref,"S"); if (input_fl == TABL) (void) SCTDIS("Warning: REF_FLAG = `S' ...",0); } } } stat = nmal = 0; while (stat == 0) { switch (input_fl) { case KEYW: stat = KEYW_INP(keynm,ncurs,cpos); break; case FIXP: FIXP_INP(shape,ref,cbuff,frame,ncurs,cpos); break; case TABL: { int aux_flag; static int nr; stat = TABL_INP(table,frame,ref,shape,&aux_flag,cpos,rbuff); if (stat == -1) /* pixel conversion error */ { stat = 0; /* reset, so we continue */ break; } if (stat == -1) break; /* pixel conversion error */ if (aux_flag > 0) { if (aux_flag >= 10) { /* we also got rotation angle */ if (shape_fl != CI) { rotang = rbuff[1]; rota_fl = (MYABS(rotang) > 0.01) ? TRUE : FALSE; if (rota_fl) { ca = cos( DEG2RAD * rotang ); sa = sin( DEG2RAD * rotang ); } } aux_flag -= 10; } if (aux_flag == 1) /* we also got color */ intens = CGN_NINT(rbuff[0]); } if (stat == 0) { if ( !rota_fl && (shape_fl == LI)) { if ( nr == 0 ) { xfig[0] = CGN_NINT( cpos[0] ); yfig[0] = CGN_NINT( cpos[1] ); xfig[1] = CGN_NINT( cpos[2] ); yfig[1] = CGN_NINT( cpos[3] ); nr++; } else { if ( (CGN_NINT(*cpos) == xfig[nr]) && (CGN_NINT(cpos[1]) == yfig[nr]) ) { xfig[++nr] = CGN_NINT( *cpos ); yfig[nr] = CGN_NINT( cpos[1] ); } else { (void) IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,nr+1,intens,1); nr = 0; } } } } else { if (nr++ > 0) { (void) IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,nr,intens,1); } } break; } case CURS: stat = CURS_INP(shape,&ncurs,cpos); break; default: SCETER(3,"DRAW: unknown input..."); break; } if (stat == 0) { nmal++; if (shape_fl == CR) /* handle CROSS */ { if ((input_fl == CURS) && (ncurs == 2)) { coord[0] = (cpos[0]+ cpos[2]) * 0.5; coord[1] = (cpos[1]+ cpos[3]) * 0.5; coord[2] = CGN_NINT( 0.5 * (cpos[3] + cpos[2] - coord[1] - *coord )); cpos[0] = coord[0]; cpos[1] = coord[1]; cpos[2] = coord[2]; } else cpos[2] = length; goto build_graph; } /* all other shapes need 2 or more cursor inputs */ if (input_fl == CURS) { if (ncurs == 0) { int xyA[5], xyB[5], statA, statB; (void) SCTDIS( usr_curs,99); Ccursin( QDSPNO,1,ncurs,xyA,&statA,xyB,&statB); cpos[2] = xyA[0]; cpos[3] = xyA[1]; if (shape_fl == CI) { rbuff[0] = cpos[0] - cpos[2]; rbuff[1] = cpos[1] - cpos[3]; cpos[2] = (float) sqrt((double)((rbuff[0]*rbuff[0]) + (rbuff[1]*rbuff[1]))); } } if (shape_fl == CI) { if (IDINUM == 11) shape[3] = '3'; /* use center + radius */ else shape[3] = '4'; /* use a rectangle */ } } build_graph: coord[0] = CGN_NINT(cpos[0]); coord[1] = CGN_NINT(cpos[1]); coord[2] = CGN_NINT(cpos[2]); coord[3] = CGN_NINT(cpos[3]); if ((shape_fl == CI) && (shape[3] == '4')) { /* for circles within rectangles we have to work */ coord[0] = CGN_NINT((cpos[0]+cpos[2])/2); coord[1] = CGN_NINT((cpos[1]+cpos[3])/2); cpos[2] = MYABS(cpos[0] - coord[0]); cpos[3] = MYABS(cpos[1] - coord[1]); coord[2] = CGN_NINT((cpos[2] + cpos[3])/2); } /* now build the desired shape */ buildgra(shape,coord,arcs,xfig,yfig,2048,&npnts); if (rota_fl) /* test, if rotation desired */ { double centx, centy, xx, yy; if (ncurs == 0) { centx = cpos[0]; centy = cpos[1]; } else { centx = (cpos[0] + cpos[2]) * 0.5; centy = (cpos[1] + cpos[3]) * 0.5; } for ( nn = 0; nn < npnts; nn++ ) { xx = ca * (xfig[nn]-centx) - sa * (yfig[nn]-centy); yy = sa * (xfig[nn]-centx) + ca * (yfig[nn]-centy); xfig[nn] = CGN_NINT( centx - xx ); yfig[nn] = CGN_NINT( centy - yy ); } } /* finally draw shape */ (void) IIGPLY_C(QDSPNO,QOVCH,xfig,yfig,npnts,intens,1); } if ( input_fl == FIXP ) stat = 1; /* only one position */ } /* closing of the while-loop */ /* save no. of coords. entered */ (void) SCKWRI("OUTPUTI",&nmal,1,1,&unit); if ( input_fl == CURS ) { (void) strcpy( output, " " ); (void) SCTDIS( output, 0 ); } else if ( input_fl == TABL ) { (void) sprintf( output, "%-d table rows processed...", nmal ); (void) SCTDIS( output, 0 ); } } if (fid > -1) goto file_loop; end_of_it: DCCLOS( QDSPNO ); Crefrovr(); return SCSEPI(); }