#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: csrcoord.c (Cursor Coordinates) * Purpose: Calculate coordinates for cursor functions * Subroutine: set_cursor_file_coords() returns: void * Subroutine: adjust_cursor_coords() returns: void * Subroutine: set_cursor_from_file_coords() returns: void * Subroutine: set_annuli_from_file_coords() returns: void * Subroutine: note_current_disp_transform() returns: void * Subroutine: report_cursor_info() returns: void * Copyright: 1999 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 4 June 1989 * {1} MVH added text cursor support 1 Jan 1991 * {2} Doug Mink added WCS info to cursor report 23 Oct 1996 * {2} Doug Mink bump WCS string to 48 from 32 6 May 1999 * {n} -- -- */ #include /* stderr, NULL, etc. */ #include #include /* X window stuff */ #include /* X window manager stuff */ #include "hfiles/color.h" /* cursor colors needed by Cursor.h */ #include "hfiles/constant.h" /* define codes */ #include "hfiles/coord.h" /* coord structs */ #include "hfiles/cursor.h" /* define cursor parameter structures */ #include "hfiles/extern.h" /* extern main SAOimage parameter structures */ #include "hfiles/wcs.h" /* World coordinate system structure */ /* Saved transform to see if it changed */ static Transform ftod; #ifdef ANSIC /* Exported declarations must be centralized before ANSI C can be used */ void set_cursor_file_coords( struct cursorRec *cursor, Transform *disptofile, int setcen); void adjust_cursor_coords( struct cursorRec *cursor, struct coordRec *coord); void set_cursor_from_file_coords( struct cursorRec *cursor, Transform *filetodisp); void set_annuli_from_file_coords( struct cursorRec *cursor, Transform *filetodisp); void note_current_disp_transform( Transform *filetodisp); void report_cursor_info( struct cursorRec *cursor); static int disp_coords_changed( Transform *filetodisp); #else void d_transform(), make_cursor(), reset_textcursor_coords(); double cursor_area(); void set_polygon_from_file_coords(), set_annuli_from_file_coords(); void set_cursor_from_file_coords(), note_current_disp_transform(); static int disp_coords_changed(); #endif /* Subroutine: set_cursor_file_coords * Purpose: Set img coords of cursor */ #ifdef ANSIC void set_cursor_file_coords( struct cursorRec *cursor, Transform *disptofile, int setcen ) #else void set_cursor_file_coords ( cursor, disptofile, setcen ) struct cursorRec *cursor; Transform *disptofile; int setcen; /* i: set-center-after-move, else set dim after size */ #endif { double ratio; if( setcen ) { d_transform(disptofile, cursor->win.X, cursor->win.Y, &cursor->file.X, &cursor->file.Y); } else { if( (ratio = disptofile->inx_outx + disptofile->inx_outy) < 0.0 ) ratio = -ratio; cursor->file.Xdim = cursor->win.rayX * ratio; cursor->file.Ydim = cursor->win.rayY * ratio; } } /* Subroutine: adjust_cursor_coords * Purpose: If the display image has been altered, change the cursor * parameters in the same way, so that the cursor has the same * relationship to the image. old cursor is not erased, image * redraw usually does that */ #ifdef ANSIC void adjust_cursor_coords ( struct cursorRec *cursor, struct coordRec *coord ) #else void adjust_cursor_coords ( cursor, coord ) struct cursorRec *cursor; struct coordRec *coord; #endif { int maincursor = 1; if( disp_coords_changed(&coord->filetodisp) ) { /* Remake the window coordinates and line drawing records */ while( cursor != NULL ) { if( cursor->type == COP_Polygon ) set_polygon_from_file_coords(cursor, &coord->filetodisp, maincursor); else { if( cursor->annuli ) set_annuli_from_file_coords(cursor, &coord->filetodisp); else set_cursor_from_file_coords(cursor, &coord->filetodisp); } /* Loop on saved cursors */ maincursor = 0; cursor = cursor->next_region; } note_current_disp_transform(&coord->filetodisp); } } /* Subroutine: set_cursor_from_file_coords * Purpose: Set cursor window coordinates from its file coordinates */ #ifdef ANSIC void set_cursor_from_file_coords( struct cursorRec *cursor, Transform *filetodisp ) #else void set_cursor_from_file_coords ( cursor, filetodisp ) struct cursorRec *cursor; Transform *filetodisp; #endif { float X, Y, ratio; double ra0, ra1, dec0, dec1, secpix; /* Get new window coordinates */ d_transform(filetodisp, (double)cursor->file.X, (double)cursor->file.Y, &X, &Y); cursor->win.X = X; cursor->win.Y = Y; cursor->win.x = (int)X; cursor->win.y = (int)Y; /* Set cursor size from command line */ if (cursor->file.Xdim < 0.0) { if (iswcs (wcs)) { (void)pix2wcs (wcs,cursor->file.X, cursor->file.Y, &ra0, &dec0); (void)pix2wcs (wcs,cursor->file.X+1.0, cursor->file.Y, &ra1, &dec1); secpix = (ra1 - ra0) * cos(degrad(dec1)) * 3600.0 ; cursor->file.Xdim = -cursor->file.Xdim / secpix; if (cursor->file.Xdim < 0) cursor->file.Xdim = -cursor->file.Xdim; } else cursor->file.Xdim = -cursor->file.Xdim; } if (cursor->file.Ydim < 0.0) { if (iswcs (wcs)) { (void)pix2wcs (wcs,cursor->file.X, cursor->file.Y, &ra0, &dec0); (void)pix2wcs (wcs,cursor->file.X, cursor->file.Y+1.0, &ra1, &dec1); secpix = (dec1 - dec0) * 3600.0; cursor->file.Ydim = -cursor->file.Ydim / secpix; if (cursor->file.Ydim < 0) cursor->file.Ydim = -cursor->file.Ydim; } else cursor->file.Ydim = -cursor->file.Ydim; } /* Convert file dimensions to display dimensions */ if( (ratio = filetodisp->inx_outx + filetodisp->inx_outy) < 0.0 ) ratio = -ratio; cursor->win.rayX = cursor->file.Xdim * ratio; cursor->win.rayY = cursor->file.Ydim * ratio; /* Make new drawing vertices */ if( cursor->type == COP_Text ) reset_textcursor_coords(cursor); else make_cursor(cursor); } /* Subroutine: set_annuli_from_file_coords * Purpose: Set annuli window coordinates from their file coordinates */ #ifdef ANSIC void set_annuli_from_file_coords ( struct cursorRec *cursor, Transform *filetodisp ) #else void set_annuli_from_file_coords ( cursor, filetodisp ) struct cursorRec *cursor; Transform *filetodisp; #endif { struct cursorRec *annulus; float X, Y, ratio; /* Get new window coordinates */ d_transform(filetodisp, (double)cursor->file.X, (double)cursor->file.Y, &X, &Y); cursor->win.X = X; cursor->win.Y = Y; cursor->win.x = (int)X; cursor->win.y = (int)Y; /* Get new window dimensions */ if( (ratio = filetodisp->inx_outx + filetodisp->inx_outy) < 0.0 ) ratio = -ratio; annulus = cursor->next_annulus; while( annulus != 0 ) { annulus->win.X = cursor->win.X; annulus->win.Y = cursor->win.Y; annulus->win.x = cursor->win.x; annulus->win.y = cursor->win.y; annulus->win.rayX = ratio * annulus->file.Xdim; annulus->win.rayY = ratio * annulus->file.Ydim; /* Make new drawing vertices */ make_cursor(annulus); annulus = annulus->next_annulus; } } /* Subroutine: note_current_disp_transform * Purpose: Note current transform */ #ifdef ANSIC void note_current_disp_transform ( Transform *filetodisp ) #else void note_current_disp_transform ( filetodisp ) Transform *filetodisp; #endif { ftod.inx_outx = filetodisp->inx_outx; ftod.inx_outy = filetodisp->inx_outy; ftod.add_outx = filetodisp->add_outx; ftod.add_outy = filetodisp->add_outy; } /* Subroutine: disp_params_changed * Purpose: Check if current transform has changed */ #ifdef ANSIC static int disp_coords_changed ( Transform *filetodisp ) #else static int disp_coords_changed ( filetodisp ) Transform *filetodisp; #endif { if( (filetodisp->inx_outx != ftod.inx_outx) || (filetodisp->inx_outy != ftod.inx_outy) || (filetodisp->add_outx != ftod.add_outx) || (filetodisp->add_outy != ftod.add_outy) ) return( 1 ); else return( 0 ); } /* Subroutine: report_cursor_info * Purpose: Calculate and report curosr params in file coordinates */ #ifdef ANSIC void report_cursor_info ( struct cursorRec *cursor ) #endif void report_cursor_info ( cursor ) struct cursorRec *cursor; { double area, areas, aread, rad, rads, ra0,dec0,ra1,dec1, degpix, secpix; double radx, rady, radxs, radys; extern double wcsdist(); int i, iswcs(); char string[64]; int lstr=48; char cursor_type[32]; switch( cursor->type ) { case COP_Circle: (void)sprintf(cursor_type,"Circle cursor"); break; case COP_PieSlice: (void)sprintf(cursor_type,"Pie cursor"); break; case COP_Ellipse: (void)sprintf(cursor_type,"Rotatable ellipse"); break; case COP_Point: (void)sprintf(cursor_type,"Point cursor"); break; case COP_Arrow: (void)sprintf(cursor_type,"Arrow pointing"); break; case COP_Box: if( cursor->rot.angle == 0.0 ) (void)sprintf(cursor_type, "Orthogonal box cursor"); else (void)sprintf(cursor_type, "Rotated box cursor"); break; case COP_Polygon: (void)sprintf(cursor_type,"Polygon cursor with %d vertices", cursor->poly_cnt); break; default: (void)sprintf(cursor_type, "Cursor"); cursor_type[0] = 0; break; } /* Calculate the new coords */ /* Now tell what and where */ /* (void)printf("%s at window x=%d, y=%d, ", cursor_type, cursor->win.x, cursor->win.y); */ if (cursor->type == COP_Polygon) (void)printf("%s at:\n", cursor_type); else { (void)printf("%s at file X=%.3f, Y=%.3f", cursor_type, cursor->file.X, cursor->file.Y); if (iswcs (wcs)) { (void)pix2wcst (wcs,cursor->file.X, cursor->file.Y,string,lstr); (void)printf(" %s\n", string); } else (void)printf("\n"); } /* Calculate scale at cursor position */ if (iswcs (wcs)) { (void)pix2wcs (wcs,cursor->file.X, cursor->file.Y,&ra0,&dec0); (void)pix2wcs (wcs,cursor->file.X, cursor->file.Y+1.0, &ra1, &dec1); degpix = dec1 - dec0; secpix = degpix * 3600.0; } else { degpix = 0.0; secpix = 0.0; } /* Calculate cursor area */ area = cursor_area(cursor, 1); areas = area * secpix * secpix; aread = area * degpix * degpix; /* Calculate cursor radius */ radx = cursor->file.Xdim; radxs = radx * secpix; rady = cursor->file.Ydim; radys = rady * secpix; switch( cursor->type ) { case COP_Circle: case COP_PieSlice: if (iswcs (wcs)) { (void)pix2wcs (wcs,cursor->file.X, cursor->file.Y,&ra0,&dec0); (void)pix2wcs (wcs,cursor->file.X, cursor->file.Y+cursor->file.Ydim, &ra1,&dec1); rads = wcsdist (ra0, dec0, ra1, dec1) * 3600; } else rads = 0.0; if (rads > 300) (void)printf("radius: %.2f pixels = %.2f arcmin, ", radx, rads/60.0); else if (rads > 0) (void)printf("radius: %.2f pixels = %.2f arcsec, ", radx, rads); else (void)printf("radius: %.2f pixels", radx); break; case COP_Ellipse: (void)printf(" angle: %6.3f rad = %6.2f deg\n", cursor->rot.angle, raddeg (cursor->rot.angle)); if (radxs > 3600.0 || radys > 3600.0) { (void)printf(" X radius: %.2f pixels = %.2f degrees, ", radx, radxs/3600.0); (void)printf("Y radius: %.2f pixels = %.2f degrees\n", rady, radys/3600.0); } else if (radxs > 300.0 || radys > 300.0) { (void)printf(" X radius: %.2f pixels = %.2f arcmin, ", radx, radxs/60.0); (void)printf("Y radius: %.2f pixels = %.2f arcmin\n", rady, radys/60.0); } else if (radxs > 0 || radys > 0) { (void)printf(" X radius: %.2f pixels = %.2f arcsec, ", radx, radxs); (void)printf("Y radius: %.2f pixels = %.2f arcsec\n", rady, radys); } else (void)printf(" X radius: %.2f pixels, Y radius: %.2f pixels\n",radx,rady); break; case COP_Box: radx = radx * 2.0; rady = rady * 2.0; radxs = radxs * 2.0; radys = radys * 2.0; if (radxs > 3600.0 || radys > 3600.0) { (void)printf(" X width: %.2f pixels = %.2f degrees, ", radx, radxs/3600.0); (void)printf("Y height: %.2f pixels = %.2f degrees\n", rady, radys/3600.0); } else if (radxs > 300.0 || radys > 300.0) { (void)printf(" X width: %.2f pixels = %.2f arcmin, ", radx, radxs/60.0); (void)printf("Y height: %.2f pixels = %.2f arcmin\n", rady, radys/60.0); } else if (radxs > 0 || radys > 0) { (void)printf(" X width: %.2f pixels = %.2f arcsec, ", radx, radxs); (void)printf("Y height: %.2f pixels = %.2f arcsec\n", rady, radys); } else (void)printf(" X width: %.2f pixels, Y height: %.2f pixels\n",radx,rady); if( cursor->rot.angle != 0.0 ) (void)printf(" angle: %6.3f rad = %6.2f deg\n", cursor->rot.angle, raddeg (cursor->rot.angle)); break; case COP_Polygon: for( i=0; ipoly_cnt; i++ ) { (void)printf(" (x=%.2f, y=%.2f)", cursor->poly[i].fileX, cursor->poly[i].fileY); if (iswcs (wcs)) { (void)pix2wcst (wcs,cursor->poly[i].fileX, cursor->poly[i].fileY, string,lstr); (void)printf(" %s", string); } (void)printf("\n"); } if (area <= 0.0 && cursor->poly_cnt > 2) (void)printf("Note: polygon is twisted.\n"); break; case COP_Point: default: break; } if (aread > 10) (void)printf(" area: %.2f pixel^2 = %.2f degree^2 \n", area, aread); else if (areas > 3599.9) (void)printf(" area: %.2f pixel^2 = %.2f arcmin^2 \n", area, areas/3600.0); else if (areas > 0.0) (void)printf(" area: %.2f pixel^2 = %.2f arcsec^2 \n", area, areas); else if (area > 0.0) (void)printf(" area: %.2f pixel^2\n", area); (void)printf("\n"); }