#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} <who> -- <does what> -- <when>
*/
#include <stdio.h> /* stderr, NULL, etc. */
#include <math.h>
#include <X11/Xlib.h> /* X window stuff */
#include <X11/Xutil.h> /* 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; i<cursor->poly_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");
}
syntax highlighted by Code2HTML, v. 0.9.1