home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / rgnanli.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  6KB  |  189 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    rgnanli.c (Region Annuli)
  6.  * Purpose:    Create annuli and parse lists of radii
  7.  * Subroutine:    fit_annuli_edge()        returns: void
  8.  * Subroutine:    new_annulus_edge()        returns: void
  9.  * Subroutine:    parse_radii()            returns: int
  10.  * Xlib calls:    none
  11.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  12.  *        You may do anything you like with this file except remove
  13.  *        this copyright.  The Smithsonian Astrophysical Observatory
  14.  *        makes no representations about the suitability of this
  15.  *        software for any purpose.  It is provided "as is" without
  16.  *        express or implied warranty.
  17.  * Modified:    {0} Michael VanHilst    initial version          11 May 1989
  18.  *        {n} <who> -- <does what> -- <when>
  19.  */
  20.  
  21. #include <stdio.h>        /* stderr, sscanf, NULL */
  22. #include <X11/Xlib.h>        /* X window stuff */
  23. #include <X11/Xutil.h>        /* X window manager stuff */
  24. #include "hfiles/cursor.h"    /* cursorRec */
  25.  
  26. /*
  27.  * Subroutine:    fit_annuli_edge
  28.  * Purpose:    If annuli edge matches previous edge, free redundancy
  29.  * Note:    By saoimage convention, base cursor record of annuli is
  30.  *        redundant to the last ring manipulated (this enables
  31.  *        the manipulation)
  32.  */
  33. void fit_annuli_edge ( cursor )
  34.      struct cursorRec *cursor;
  35. {
  36.   struct cursorRec *region;
  37.   struct cursorRec *edge;
  38.   int not_different();
  39.   void free_cursor();
  40.  
  41.   region = cursor->next_region;
  42.   edge = region->next_region;
  43.   while( edge->next_annulus != NULL )
  44.     edge = edge->next_annulus;
  45.   if( (region->type == edge->type) &&
  46.       not_different(region->rot.angle, edge->rot.angle) &&
  47.       not_different(region->file.X, edge->file.X) &&
  48.       not_different(region->file.Y, edge->file.Y) && 
  49.       not_different(region->file.Xdim, edge->file.Xdim) &&
  50.       not_different(region->file.Ydim, edge->file.Ydim) ) {
  51.     /* region is part of annuli, not a separate region */
  52.     cursor->next_region = region->next_region;
  53.     if( cursor->next_region->annuli ) {
  54.       /* if annuli exist, we don't need this edge */
  55.       free_cursor(region);
  56.     } else {
  57.       /* if creating the first ring around a cursor, make redundant */
  58.       edge->annuli = 1;
  59.       edge->next_annulus = region;
  60.     }
  61.   }
  62. }
  63.  
  64. /*
  65.  * Subroutine:    new_annuli_edge
  66.  * Purpose:    reposition region to be an annular edge
  67.  */
  68. void new_annulus_edge ( cursor )
  69.      struct cursorRec *cursor;
  70. {
  71.   struct cursorRec *region;
  72.   struct cursorRec *edge;
  73.  
  74.   edge = cursor->next_region;
  75.   region = edge->next_region;
  76.   cursor->next_region = region;
  77.   if( region->annuli == 0 )
  78.     /* this is an error condition (see fit_annuli_edge above) */
  79.     region->annuli = 1;
  80.   while( region->next_annulus != NULL )
  81.     region = region->next_annulus;
  82.   region->next_annulus = edge;
  83. }
  84.  
  85. /*
  86.  * Subroutine:    parse_radii
  87.  * Purpose:    Get a list of radii from line
  88.  * Returns:    Number of radii found
  89.  * Note:    "vala valb valc ..." and "val1 val2 n=int" are both
  90.  *        permitted syntax forms
  91.  */
  92. int parse_radii ( line, radius, maxcnt )
  93.      char *line;    /* i: string with first radius as next token */
  94.      float *radius;    /* o: buffer for float radius vals */
  95.      int maxcnt;    /* i: size of radius buffer */
  96. {
  97.   int i, cnt;
  98.   static int expand_radii();
  99.   static char *got_nequal();
  100.   char *next_token();
  101.  
  102.   i = 0;
  103.   /* while there are tokens, look at the next one */
  104.   while( (line != 0) && (i < maxcnt) ) {
  105.     if( sscanf(line, "%f", &radius[i]) == 1 ) {
  106.       /* next token was a number, got next radius */
  107.       i++;
  108.     } else {
  109.       /* next token not a number, check for n=integer statement */
  110.       if( ((line = got_nequal(line)) != NULL) &&
  111.       (sscanf(line, "%d", &cnt) == 1) ) {
  112.     /* got n=cnt, add cnt radii between previous two radii */
  113.     i = expand_radii(radius, i, maxcnt, cnt);
  114.       } else {
  115.     /* token neither radius nor n=int, must be error, keep prior radii */
  116.     (void)fprintf(stderr,"WARNING: cannot parse radii params: %s\n",line);
  117.         return( i );
  118.       }
  119.     }
  120.     line = next_token(line, 1);
  121.   }
  122.   return( i );
  123. }
  124.  
  125. /*
  126.  * Subroutine:    expand_radii
  127.  * Purpose:    Given an n=cnt, install cnt radii in list between last
  128.  *        two radii
  129.  * Returns:    Total number of radii in radius buffer
  130.  */
  131. static int expand_radii ( radius, i, maxcnt, cnt )
  132.      float *radius;    /* i/o: array list of radii */
  133.      int i;        /* i: current array size */
  134.      int maxcnt;    /* i: maximum allowed size */
  135.      int cnt;        /* i: number of bands to divide last interval */
  136. {
  137.   double first, last, inc;
  138.  
  139.   /* last radius will be placed at end of new listing */
  140.   i--;
  141.   /* get the limits and the increment to make cnt bands in this interval */
  142.   last = radius[i];
  143.   first = radius[i-1];
  144.   inc = (last - first) / (double)cnt;
  145.   /* set cnt to the last index, and move last radius */
  146.   cnt += i-1;
  147.   /* do not exceed max array index */
  148.   if( cnt > maxcnt )
  149.     cnt = maxcnt - 1;
  150.   else
  151.     radius[cnt] = radius[i];
  152.   /* fill in the intermediate radii */
  153.   while( i<cnt ) {
  154.     first += inc;
  155.     radius[i++] = first;
  156.   }
  157.   return( cnt + 1 );
  158. }
  159.  
  160. /*
  161.  * Subroutine:    got_nequal
  162.  * Purpose:    Determine is line has tokens of form n= or n =
  163.  * Returns:    Ptr to char after '=', else NULL
  164.  * Note:    The n of n= can be any non-space char(s) except '='
  165.  */
  166. static char *got_nequal ( line )
  167.      char *line;
  168. {
  169.   int i = 0;
  170.   /* check for premature end */
  171.   if( (line[i] == '\0') || (line[i] == '\n') )
  172.     return( NULL );
  173.   /* advance to token */
  174.   while( line[i] == ' ' )
  175.     i++;
  176.   /* advance to end of token, or equal sign */
  177.   while( (line[i] != ' ') && (line[i] != '\0') &&
  178.      (line[i] != '\n') && (line[i] != '=') )
  179.     i++;
  180.   /* if stopped on space, advance to next symbol */
  181.   while( line[i] == ' ' )
  182.     i++;
  183.   /* symbol must be an equal sign, or we have an error */
  184.   if ( (line[i] == '=') && (line[i+1] != '\0') && (line[i+1] != '\n') )
  185.     return( &line[i+1] );
  186.   else
  187.     return( NULL );
  188. }
  189.