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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    grphpos.c (Color Graph Position)
  6.  * Subroutine:    select_best_hash_position()        returns: int
  7.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  8.  *        You may do anything you like with this file except remove
  9.  *        this copyright.  The Smithsonian Astrophysical Observatory
  10.  *        makes no representations about the suitability of this
  11.  *        software for any purpose.  It is provided "as is" without
  12.  *        express or implied warranty.
  13.  * Modified:    {0} Michael VanHilst    initial version         11 June 1989
  14.  *        {n} <who> -- <does what> -- <when>
  15.  */
  16.  
  17. #include <X11/Xlib.h>        /* X window stuff */
  18.  
  19. #define ABS(a) ((a) < 0 ? (-(a)) : (a))
  20.  
  21. /*
  22.  * Subroutine:    select_best_hash_position
  23.  * Purpose:    Select the best place in the list for a new hash mark, based
  24.  *        on its coordinates and those of existing hash marks.
  25.  * Returns:    The hash index to give the new hash mark.
  26.  * Note:    match is used to force new vertex to use same cell_level as
  27.  *        the vertex which it is next to. When vertexes have same
  28.  *        screen coordinate, converting to a real may produce values
  29.  *        in the wrong order.
  30.  */
  31. int select_best_hash_position ( x, y, hash, hash_cnt, match, vertical )
  32.      int x, y;
  33.      XRectangle hash[];
  34.      int hash_cnt;
  35.      int *match;        /* o: close hash with same x value */
  36.      int vertical;        /* i: flag for vertical, else horizontal */
  37. {
  38.   int i;
  39.  
  40.   /* initially no existing hash with which to match level */
  41.   *match = -1;
  42.   if( hash_cnt == 0 )
  43.     return( 0 );
  44.   if( vertical ) {
  45.     /* vertical */
  46.     for( i = 0; ((i < hash_cnt) && (y < hash[i].y)); i++ );
  47.     if( (i == hash_cnt) || (y > hash[i].y) )
  48.       /* y between this and previous hash mark (or beyond either end) */
  49.       return( i );
  50.     *match = i;
  51.     /* else y same as hash i's y */
  52.     if( y == (hash_cnt - 1) ) {
  53.       /* same as last hash mark */
  54.       if( x > hash[i].x ) {
  55.     if( hash[i-1].x > hash[i].x )
  56.       return( i );
  57.     else
  58.       return( i+1 );
  59.       } else {
  60.     if( hash[i-1].x < hash[i].x )
  61.       return( i );
  62.     else
  63.       return( i+1 );
  64.       }
  65.     }
  66.     if( y > hash[i+1].y ) {
  67.       /* same y as one other hash mark */
  68.       if( i == 0 ) {
  69.     /* same as first one */
  70.     if( x > hash[i].x ) {
  71.       if( hash[i+1].x < hash[i].x )
  72.         return( i );
  73.       else
  74.         return( i+1 );
  75.     } else {
  76.       if( hash[i+1].x < hash[i].x )
  77.         return( i );
  78.       else
  79.         return( i+1 );
  80.     }
  81.       }
  82.       /* not same as first one */
  83.       if( x > hash[i].x ) {
  84.     if( hash[i-1].x > hash[i+1].x )
  85.       return( i );
  86.     else
  87.       return( i+1 );
  88.       } else {
  89.     if( hash[i-1].x < hash[i+1].x )
  90.       return( i );
  91.     else
  92.       return( i+1 );
  93.       }
  94.     }
  95.     {
  96.       int close, dx, j;
  97.       /* y matches two or more hashes' y */
  98.       close = ABS(x - hash[i].x);
  99.       /* advance to closest hash with same y */
  100.       for( j=i+1; (j<hash_cnt) && (hash[j].y == y); j++ ) {
  101.     dx = ABS(x - hash[j].x);
  102.     if( dx <= close ) {
  103.       close = dx;
  104.       i = j;
  105.     }
  106.       }
  107.       *match = i;
  108.     }
  109.     if( i == 0 ) {
  110.       /* first hash (second also same y) */
  111.       if( x > hash[i].x ) {
  112.     if( hash[i+1].x < hash[i].x )
  113.       return( i );
  114.     else
  115.       return( i+1 );
  116.       } else {
  117.     if( hash[i+1].x > hash[i].x )
  118.       return( i );
  119.     else
  120.       return( i+1 );
  121.       }
  122.     }
  123.     if( i == (hash_cnt - 1) ) {
  124.       /* last hash (previous also same y) */
  125.       if( x > hash[i].x ) {
  126.     if( hash[i-1].x > hash[i].x )
  127.       return( i );
  128.     else
  129.       return( i+1 );
  130.       } else {
  131.     if( hash[i-1].x < hash[i].x )
  132.       return( i );
  133.     else
  134.       return( i+1 );
  135.       }
  136.     }
  137.     /* not an extreme hash, at least one other with same y */
  138.     if( hash[i-1].y == hash[i+1].y ) {
  139.       /* middle of three with same y */
  140.       if( x > hash[i].x ) {
  141.     if( hash[i-1].x > hash[i+1].x )
  142.       return( i );
  143.     else
  144.       return( i+1 );
  145.       } else {
  146.     if( hash[i-1].x < hash[i+1].x )
  147.       return( i );
  148.     else
  149.       return( i+1 );
  150.       }
  151.     }
  152.     if( hash[i-1].y == y ) {
  153.       if( x > hash[i].x ) {
  154.     if( hash[i-1].x > hash[i].x )
  155.       /* new position between two with same y */
  156.       return( i );
  157.     else
  158.       return( i+1 );
  159.       } else {
  160.     if( hash[i-1].x < hash[i].x )
  161.       /* new position between two with same y */
  162.       return( i );
  163.     else
  164.       return( i+1 );
  165.       }
  166.     } else {
  167.       if( x > hash[i].x ) {
  168.     if( hash[i+1].x > hash[i].x )
  169.       /* new position between two with same y */
  170.       return( i+1 );
  171.     else
  172.       return( i );
  173.       } else {
  174.     if( hash[i+1].x < hash[i].x )
  175.       /* new position between two with same y */
  176.       return( i+1 );
  177.     else
  178.       return( i );
  179.       }
  180.     }
  181.   } else {
  182.     /* horizontal */
  183.     for( i = 0; ((i < hash_cnt) && (x > hash[i].x)); i++ );
  184.     if( (i == hash_cnt) || (x < hash[i].x) )
  185.       /* x between this an previous hash mark (or beyond either end) */
  186.       return( i );
  187.     /* else x same as hash i's x */
  188.     *match = i;
  189.     if( x == (hash_cnt - 1) ) {
  190.       /* same as last hash mark */
  191.       if( y > hash[i].y ) {
  192.     if( hash[i-1].y > hash[i].y )
  193.       return( i );
  194.     else
  195.       return( i+1 );
  196.       } else {
  197.     if( hash[i-1].y < hash[i].y )
  198.       return( i );
  199.     else
  200.       return( i+1 );
  201.       }
  202.     }
  203.     if( x < hash[i+1].x ) {
  204.       /* same x as one other hash mark */
  205.       if( i == 0 ) {
  206.     /* same as first one */
  207.     if( y > hash[i].y ) {
  208.       if( hash[i+1].y < hash[i].y )
  209.         return( i );
  210.       else
  211.         return( i+1 );
  212.     } else {
  213.       if( hash[i+1].y < hash[i].y )
  214.         return( i );
  215.       else
  216.         return( i+1 );
  217.     }
  218.       }
  219.       /* not same as first one */
  220.       if( y > hash[i].y ) {
  221.     if( hash[i-1].y > hash[i+1].y )
  222.       return( i );
  223.     else
  224.       return( i+1 );
  225.       } else {
  226.     if( hash[i-1].y < hash[i+1].y )
  227.       return( i );
  228.     else
  229.       return( i+1 );
  230.       }
  231.     }
  232.     {
  233.       int close, dy, j;
  234.       /* x matches two or more hashes' x */
  235.       close = ABS(y - hash[i].y);
  236.       /* advance to closest hash with same x */
  237.       for( j=i+1; (j<hash_cnt) && (hash[j].x == x); j++ ) {
  238.     dy = ABS(y - hash[j].y);
  239.     if( dy <= close ) {
  240.       close = dy;
  241.       i = j;
  242.     }
  243.       }
  244.       *match = i;
  245.     }
  246.     if( i == 0 ) {
  247.       /* first hash (second also same x) */
  248.       if( y > hash[i].y ) {
  249.     if( hash[i+1].y < hash[i].y )
  250.       return( i );
  251.     else
  252.       return( i+1 );
  253.       } else {
  254.     if( hash[i+1].y > hash[i].y )
  255.       return( i );
  256.     else
  257.       return( i+1 );
  258.       }
  259.     }
  260.     if( i == (hash_cnt - 1) ) {
  261.       /* last hash (previous also same x) */
  262.       if( y > hash[i].y ) {
  263.     if( hash[i-1].y > hash[i].y )
  264.       return( i );
  265.     else
  266.       return( i+1 );
  267.       } else {
  268.     if( hash[i-1].y < hash[i].y )
  269.       return( i );
  270.     else
  271.       return( i+1 );
  272.       }
  273.     }
  274.     /* not an extreme hash, at least one other with same x */
  275.     if( hash[i-1].x == hash[i+1].x ) {
  276.       /* middle of three with same x */
  277.       if( y > hash[i].y ) {
  278.     if( hash[i-1].y > hash[i+1].y )
  279.       return( i );
  280.     else
  281.       return( i+1 );
  282.       } else {
  283.     if( hash[i-1].y < hash[i+1].y )
  284.       return( i );
  285.     else
  286.       return( i+1 );
  287.       }
  288.     }
  289.     if( hash[i-1].x == x ) {
  290.       if( y > hash[i].y ) {
  291.     if( hash[i-1].y > hash[i].y )
  292.       /* new position between two with same x */
  293.       return( i );
  294.     else
  295.       return( i+1 );
  296.       } else {
  297.     if( hash[i-1].y < hash[i].y )
  298.       /* new position between two with same x */
  299.       return( i );
  300.     else
  301.       return( i+1 );
  302.       }
  303.     } else {
  304.       if( y > hash[i].y ) {
  305.     if( hash[i+1].y > hash[i].y )
  306.       /* new position between two with same x */
  307.       return( i+1 );
  308.     else
  309.       return( i );
  310.       } else {
  311.     if( hash[i+1].y < hash[i].y )
  312.       /* new position between two with same x */
  313.       return( i+1 );
  314.     else
  315.       return( i );
  316.       }
  317.     }
  318.   }
  319. }
  320.