home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 505a.lha / GrapicsGems / DoubleLine.c < prev    next >
Text File  |  1991-05-01  |  5KB  |  193 lines

  1. /*
  2. Symmetric Double Step Line Algorithm
  3. by Brian Wyvill
  4. from "Graphics Gems", Academic Press, 1990
  5. */
  6.  
  7. #define swap(a,b)           {a^=b; b^=a; a^=b;}
  8. #define absolute(i,j,k)     ( (i-j)*(k = ( (i-j)<0 ? -1 : 1)))
  9. int
  10. symwuline(a1, b1, a2, b2) int a1, b1, a2, b2;
  11. {
  12.     int           dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left;
  13.     int           x1, y1;
  14.     int           sign_x, sign_y, step, reverse, i;
  15.  
  16.     dx = absolute(a2, a1, sign_x);
  17.     dy = absolute(b2, b1, sign_y);
  18.     /* decide increment sign by the slope sign */
  19.     if (sign_x == sign_y)
  20.         step = 1;
  21.     else
  22.         step = -1;
  23.  
  24.     if (dy > dx) {        /* chooses axis of greatest movement (make
  25.                           * dx) */
  26.         swap(a1, b1);
  27.         swap(a2, b2);
  28.         swap(dx, dy);
  29.         reverse = 1;
  30.     } else
  31.         reverse = 0;
  32.     /* note error check for dx==0 should be included here */
  33.     if (a1 > a2) {        /* start from the smaller coordinate */
  34.         x = a2;
  35.         y = b2;
  36.         x1 = a1;
  37.         y1 = b1;
  38.     } else {
  39.         x = a1;
  40.         y = b1;
  41.         x1 = a2;
  42.         y1 = b2;
  43.     }
  44.  
  45.  
  46.     /* Note dx=n implies 0 - n or (dx+1) pixels to be set */
  47.     /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */
  48.     /* In fact (dx-1)/4 as 2 pixels are already plottted */
  49.     xend = (dx - 1) / 4;
  50.     pixels_left = (dx - 1) % 4;    /* number of pixels left over at the
  51.                                   * end */
  52.     plot(x, y, reverse);
  53.     plot(x1, y1, reverse);    /* plot first two points */
  54.     incr2 = 4 * dy - 2 * dx;
  55.     if (incr2 < 0) {    /* slope less than 1/2 */
  56.         c = 2 * dy;
  57.         incr1 = 2 * c;
  58.         D = incr1 - dx;
  59.  
  60.         for (i = 0; i < xend; i++) {    /* plotting loop */
  61.             ++x;
  62.             --x1;
  63.             if (D < 0) {
  64.                               /* pattern 1 forwards */
  65.                 plot(x, y, reverse);
  66.                 plot(++x, y, reverse);
  67.                                 /* pattern 1 backwards */
  68.                 plot(x1, y1, reverse);
  69.                 plot(--x1, y1, reverse);
  70.                 D += incr1;
  71.             } else {
  72.                 if (D < c) {
  73.                     /* pattern 2 forwards */
  74.                     plot(x, y, reverse);
  75.                     plot(++x, y += step, reverse);
  76.                     /* pattern 2 backwards */
  77.                     plot(x1, y1, reverse);
  78.                     plot(--x1, y1 -= step, reverse);    
  79.                 } else {
  80.                         /* pattern 3 forwards */
  81.                     plot(x, y += step, reverse);
  82.                     plot(++x, y, reverse);
  83.                     /* pattern 3 backwards */
  84.                     plot(x1, y1 -= step, reverse);
  85.                     plot(--x1, y1, reverse);
  86.                 }
  87.                 D + = incr2;
  88.             }
  89.         }        /* end for */
  90.  
  91.         /* plot last pattern */
  92.         if (pixels_left) {
  93.             if (D < 0) {
  94.                 plot(++x, y, reverse);    /* pattern 1 */
  95.                 if (pixels_left > 1)
  96.                     plot(++x, y, reverse);
  97.                 if (pixels_left > 2)
  98.                     plot(--x1, y1, reverse);
  99.             } else {
  100.                 if (D < c) {
  101.                     plot(++x, y, reverse);    /* pattern 2  */
  102.                     if (pixels_left > 1)
  103.                         plot(++x, y += step, reverse);
  104.                     if (pixels_left > 2)
  105.                         plot(--x1, y1, reverse);
  106.                 } else {
  107.                   /* pattern 3 */
  108.                     plot(++x, y += step, reverse);
  109.                     if (pixels_left > 1)
  110.                         plot(++x, y, reverse);
  111.                     if (pixels_left > 2)
  112.                         plot(--x1, y1 -= step, reverse);
  113.                 }
  114.             }
  115.         }        /* end if pixels_left */
  116.     }
  117.     /* end slope < 1/2 */
  118.     else {            /* slope greater than 1/2 */
  119.         c = 2 * (dy - dx);
  120.         incr1 = 2 * c;
  121.         D = incr1 + dx;
  122.         for (i = 0; i < xend; i++) {
  123.             ++x;
  124.             --x1;
  125.             if (D > 0) {
  126.               /* pattern 4 forwards */
  127.                 plot(x, y += step, reverse);
  128.                 plot(++x, y += step, reverse);
  129.               /* pattern 4 backwards */
  130.                 plot(x1, y1 -= step, reverse);
  131.                 plot(--x1, y1 -= step, reverse);
  132.                 D += incr1;
  133.             } else {
  134.                 if (D < c) {
  135.                   /* pattern 2 forwards */
  136.                     plot(x, y, reverse);
  137.                     plot(++x, y += step, reverse);
  138.  
  139.                    /* pattern 2 backwards */
  140.                     plot(x1, y1, reverse);
  141.                     plot(--x1, y1 -= step, reverse);
  142.                 } else {
  143.                   /* pattern 3 forwards */
  144.                     plot(x, y += step, reverse);
  145.                     plot(++x, y, reverse);
  146.                   /* pattern 3 backwards */
  147.                     plot(x1, y1 -= step, reverse);
  148.                     plot(--x1, y1, reverse);
  149.                 }
  150.                 D += incr2;
  151.             }
  152.         }        /* end for */
  153.         /* plot last pattern */
  154.         if (pixels_left) {
  155.             if (D > 0) {
  156.                 plot(++x, y += step, reverse);    /* pattern 4 */
  157.                 if (pixels_left > 1)
  158.                     plot(++x, y += step, reverse);
  159.                 if (pixels_left > 2)
  160.                     plot(--x1, y1 -= step, reverse);
  161.             } else {
  162.                 if (D < c) {
  163.                     plot(++x, y, reverse);    /* pattern 2  */
  164.                     if (pixels_left > 1)
  165.                         plot(++x, y += step, reverse);
  166.                     if (pixels_left > 2)
  167.                         plot(--x1, y1, reverse);
  168.                 } else {
  169.                   /* pattern 3 */
  170.                     plot(++x, y += step, reverse);
  171.                     if (pixels_left > 1)
  172.                         plot(++x, y, reverse);
  173.                     if (pixels_left > 2) {
  174.                         if (D > c) /* step 3 */
  175.                            plot(--x1, y1 -= step, reverse);
  176.                         else /* step 2 */
  177.                             plot(--x1, y1, reverse);
  178.                                  }
  179.                 }
  180.             }
  181.         }
  182.     }
  183. }
  184. /* non-zero flag indicates the pixels needing swap back. */
  185. plot(x, y, flag) int x, y, flag;
  186. {
  187.     if (flag)
  188.         setpixel(y, x);
  189.     else
  190.         setpixel(x, y);
  191. }
  192.  
  193.