Logo Search packages:      
Sourcecode: saoimage version File versions

csrcoord.c

#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");   
}

Generated by  Doxygen 1.6.0   Back to index