home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 505a.lha / GrapicsGems / 2DClip / bio.c next >
C/C++ Source or Header  |  1991-05-01  |  3KB  |  177 lines

  1.  
  2. /*
  3.  * file  bio.c
  4.  *    contains the basic operations
  5.  *
  6.  */
  7. #include    <stdio.h>
  8. #include    "GraphicsGems.h"
  9. #include    "line.h"
  10.  
  11. /*
  12.  * def_contour
  13.  *
  14.  *    Purpose:
  15.  *    add a contour to the list
  16.  *    NOTE: coordinates must already be converted into longs!
  17.  *    
  18.  *    x    x coordinates of the end points of segments
  19.  *    y    y coordinates of the end points of segments
  20.  *    n    number of coordinate pairs
  21.  *    no    contour number (id), does no have to be unique!
  22.  *    type    type of clip operation desired CLIP_NORMAL means
  23.  *        clip everything inside the contour
  24.  */
  25. def_contour(x, y, n, no, type)
  26. long    x[], y[];
  27. int    n, no, type;
  28. {
  29.     short    i;
  30.     long    dx1, dx2, dy1, dy2;
  31.     long    minx, miny, maxx, maxy;
  32.     CONTOUR    *cp;
  33.     SEGMENT    *sp, *spp;
  34.  
  35.     if((cp = CL) == (CONTOUR *)NULL) {
  36.         cp = CL = NEWTYPE(CONTOUR);
  37.     }
  38.     else {
  39.         while(cp->_next != (CONTOUR *)NULL)
  40.             cp = cp->_next;
  41.         i = cp->_no;
  42.         cp = cp->_next = NEWTYPE(CONTOUR);
  43.     }
  44.  
  45.     cp->_next = (CONTOUR *)NULL;
  46.     cp->_no = no;
  47.     SET_ON(cp);
  48.     if(type == CLIP_NORMAL)
  49.         SET_INVERSE(cp);
  50.     else
  51.         SET_NORMAL(cp);
  52.     minx = miny = 1000000;
  53.     maxx = maxy = -1;
  54.     for(i=0; i<n; i++) {
  55.         if(i == 0) {
  56.             cp->_s = sp = NEWTYPE(SEGMENT);
  57.             sp->_from._x = x[0];
  58.             sp->_from._y = y[0];
  59.             sp->_to._x   = x[1];
  60.             sp->_to._y   = y[1];
  61.         }
  62.         else {
  63.         /*
  64.          * if necessary stretch the contour
  65.          * and skip the point
  66.          */
  67.             dx1 = sp->_to._x - sp->_from._x;
  68.             dy1 = sp->_to._y - sp->_from._y;
  69.             dx2 = x[(i == n-1) ? 0 : i+1] - sp->_to._x;
  70.             dy2 = y[(i == n-1) ? 0 : i+1] - sp->_to._y;
  71.             if(dy2*dx1 == dy1*dx2) {
  72.                 sp->_to._x = x[(i == n-1) ? 0 : i+1];
  73.                 sp->_to._y = y[(i == n-1) ? 0 : i+1];
  74.             }
  75.             else {
  76.                 spp = sp;
  77.                 sp = sp->_next =  NEWTYPE(SEGMENT);
  78.                 sp->_prev = spp;
  79.                 sp->_from._x = x[i];
  80.                 sp->_from._y = y[i];
  81.                 sp->_to._x = x[(i == n-1) ? 0 : i+1];
  82.                 sp->_to._y = y[(i == n-1) ? 0 : i+1];
  83.             }
  84.         }
  85.  
  86. /*
  87.  * calculate the enclosing box
  88.  */
  89.         if(x[i] < minx) 
  90.             minx = x[i];
  91.         if(x[i] > maxx)
  92.             maxx = x[i];
  93.         if(y[i] < miny)
  94.             miny = y[i];
  95.         if(y[i] > maxy)
  96.             maxy = y[i];
  97.             
  98.     }
  99.     cp->_minx = minx;
  100.     cp->_maxx = maxx;
  101.     cp->_miny = miny;
  102.     cp->_maxy = maxy;
  103.     sp->_next = cp->_s;
  104.     cp->_s->_prev = sp;
  105.     cp->_next = (CONTOUR *)NULL;
  106. }
  107.  
  108. /*
  109.  * get_contour_ptr
  110.  *
  111.  *    PURPOSE
  112.  *    get the pointer to a contour given its id
  113.  *    with multiple id's first fit algorithm is
  114.  *    used. Returns NULL in case of error.
  115.  *
  116.  *    no    id of contour
  117.  */
  118. CONTOUR    *get_contour_ptr(no)
  119. int    no;
  120. {
  121.     CONTOUR    *cp;
  122.  
  123.     if((cp = CL) == (CONTOUR *)NULL) 
  124.         return((CONTOUR *)NULL);
  125.     else {
  126.         while(cp != (CONTOUR *)NULL) {
  127.             if(cp->_no == no)
  128.                 return(cp);
  129.             else
  130.                 cp = cp->_next;
  131.         }
  132.         return((CONTOUR *)NULL);
  133.     }
  134. }
  135.  
  136.  
  137. /*
  138.  * del_contour
  139.  *
  140.  *    PURPOSE
  141.  *    delete contour(s) from the list with id
  142.  *    no
  143.  */
  144. del_contour(no)
  145. int    no;
  146. {
  147.     CONTOUR    *cp, *cpp;
  148.     CONTOUR    *qp = (CONTOUR *)NULL;
  149.     SEGMENT    *sp, *spp;
  150.  
  151.     if((cp = CL) == (CONTOUR *)NULL)
  152.         return;
  153.     while(cp != (CONTOUR *)NULL) {
  154.         if(cp->_no == no) {
  155.             sp = cp->_s;
  156.             do {
  157.                 spp = sp->_next;
  158.                 free(sp);
  159.                 sp = spp;
  160.             } while(sp != cp->_s);
  161.             cpp = cp->_next;
  162.             free(cp);
  163.             if(qp)
  164.                 qp->_next = cpp;
  165.             else
  166.                 CL = cpp;
  167.             cp = cpp;
  168.         } 
  169.         else {
  170.             qp = cp;
  171.             cp = cp->_next;
  172.         }
  173.     }
  174. }
  175.  
  176.  
  177.