home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / VOGLE.ZIP / VOGLE / SRC / CLIP.C < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-11  |  3.3 KB  |  172 lines

  1. #include "vogle.h"
  2.  
  3. static int planes[] = {'\01', '\02', '\04', '\010', '\020', '\040'};
  4.  
  5. float wc[2][6];
  6.  
  7. /*
  8.  * MakeEdgeCoords
  9.  *
  10.  * calculates distance from point to each clipping plane in Homogeneous
  11.  * clipping coordinates. Return code if on outside of any clipping plane
  12.  * is non-zero.
  13.  *
  14.  */
  15. int
  16. MakeEdgeCoords(i, p)
  17.     int    i;
  18.     Vector    p;
  19. {
  20.     int    j, k = 0;
  21.  
  22.     wc[i][0] = p[V_W] + p[V_X];
  23.     wc[i][1] = p[V_W] - p[V_X];
  24.     wc[i][2] = p[V_W] + p[V_Y];
  25.     wc[i][3] = p[V_W] - p[V_Y];
  26.     wc[i][4] = p[V_W] + p[V_Z];
  27.     wc[i][5] = p[V_W] - p[V_Z];
  28.     
  29.     for (j = 0; j < 6; j++)
  30.         if (wc[i][j] < 0.0)
  31.             k |= planes[j];
  32.  
  33.     return(k);
  34. }
  35.  
  36. /*
  37.  * clip
  38.  *
  39.  * Clips a 3D line using Homogeneous clipping.
  40.  * Reference: Newman and Sproull
  41.  *
  42.  */
  43. void
  44. clip(p0, p1)
  45.     register Vector    p0, p1;
  46. {
  47.     float    t, t1, t2, dx, dy, dz, dw;
  48.     int    vx, vy, c1, c2, i;
  49.  
  50.     c1 = MakeEdgeCoords(0, p0);
  51.     c2 = MakeEdgeCoords(1, p1);
  52.  
  53.     if (!(c1 & c2)) {
  54.  
  55.         t1 = 0.0;
  56.         t2 = 1.0;
  57.         for (i = 0; i < 6; i++)
  58.             if (wc[0][i] < 0.0 || wc[1][i] < 0.0) {
  59.                 t = wc[0][i] / (wc[0][i] - wc[1][i]);
  60.                 if (wc[0][i] < 0.0) {
  61.                     if (t > t1) 
  62.                         t1 = t;
  63.                 } else if (t < t2) 
  64.                         t2 = t;
  65.             }
  66.          
  67.          if (t2 >= t1) {
  68.             vdevice.cpVvalid = 1;
  69.             dx = p1[V_X] - p0[V_X];
  70.             dy = p1[V_Y] - p0[V_Y];
  71.             dz = p1[V_Z] - p0[V_Z];
  72.             dw = p1[V_W] - p0[V_W];
  73.             if (t2 != 1.0) {
  74.                 p1[V_X] = p0[V_X] + t2 * dx;
  75.                 p1[V_Y] = p0[V_Y] + t2 * dy;
  76.                 p1[V_Z] = p0[V_Z] + t2 * dz;
  77.                 p1[V_W] = p0[V_W] + t2 * dw;
  78.                 vdevice.cpVvalid = 0;
  79.             }
  80.             if (t1 != 0.0) {
  81.                 p0[V_X] = p0[V_X] + t1 * dx;
  82.                 p0[V_Y] = p0[V_Y] + t1 * dy;
  83.                 p0[V_Z] = p0[V_Z] + t1 * dz;
  84.                 p0[V_W] = p0[V_W] + t1 * dw;
  85.             }
  86.             vdevice.cpVx = WtoVx(p0);
  87.             vdevice.cpVy = WtoVy(p0);
  88.  
  89.             if (vdevice.attr->a.style) {
  90.                 dashline(p0, p1);
  91.                 return;
  92.             }
  93.  
  94.             vx = WtoVx(p1);
  95.             vy = WtoVy(p1);
  96.             (*vdevice.dev.Vdraw)(vx, vy);
  97.             vdevice.cpVx = vx;
  98.             vdevice.cpVy = vy;
  99.         }
  100.     }
  101. }
  102.  
  103.  
  104. /*
  105.  * quickclip
  106.  *
  107.  * A variation on the above that assumes p0 is a valid position in device coords
  108.  *
  109.  */
  110. void
  111. quickclip(p0, p1)
  112.     register Vector    p0, p1;
  113. {
  114.     register float    t, t1;
  115.     register int    vx, vy, i;
  116.  
  117.     t1 = 1.0;
  118.  
  119.     wc[0][0] = p0[V_W] + p0[V_X];
  120.     wc[0][1] = p0[V_W] - p0[V_X];
  121.     wc[0][2] = p0[V_W] + p0[V_Y];
  122.     wc[0][3] = p0[V_W] - p0[V_Y];
  123.     wc[0][4] = p0[V_W] + p0[V_Z];
  124.     wc[0][5] = p0[V_W] - p0[V_Z];
  125.     wc[1][0] = p1[V_W] + p1[V_X];
  126.     wc[1][1] = p1[V_W] - p1[V_X];
  127.     wc[1][2] = p1[V_W] + p1[V_Y];
  128.     wc[1][3] = p1[V_W] - p1[V_Y];
  129.     wc[1][4] = p1[V_W] + p1[V_Z];
  130.     wc[1][5] = p1[V_W] - p1[V_Z];
  131.  
  132.     for (i = 0; i < 6; i++)
  133.         if (wc[0][i] >= 0.0 && wc[1][i] < 0.0) {
  134.             t = wc[0][i] / (wc[0][i] - wc[1][i]);
  135.             if (t < t1)
  136.                     t1 = t;
  137.         }
  138.      
  139.     vdevice.cpVvalid = 1;
  140.     if (t1 != 1.0) {
  141.         p1[V_X] = p0[V_X] + t1 * (p1[V_X] - p0[V_X]);
  142.         p1[V_Y] = p0[V_Y] + t1 * (p1[V_Y] - p0[V_Y]);
  143.         p1[V_Z] = p0[V_Z] + t1 * (p1[V_Z] - p0[V_Z]);
  144.         p1[V_W] = p0[V_W] + t1 * (p1[V_W] - p0[V_W]);
  145.         vdevice.cpVvalid = 0;
  146.     }
  147.  
  148.     if (vdevice.attr->a.style) {
  149.         dashline(p0, p1);
  150.         return;
  151.     }
  152.  
  153.     vx = WtoVx(p1);
  154.     vy = WtoVy(p1);
  155.  
  156.     (*vdevice.dev.Vdraw)(vx, vy);
  157.     vdevice.cpVx = vx;
  158.     vdevice.cpVy = vy;
  159. }
  160.  
  161. /*
  162.  * clipping
  163.  *
  164.  *     Turns clipping on or off.
  165.  */
  166. void
  167. clipping(onoff)
  168.     int    onoff;
  169. {
  170.     vdevice.clipoff = !onoff;
  171. }
  172.