home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / fermiVogle.tar.Z / fermiVogle.tar / devel / src / clip.c < prev    next >
C/C++ Source or Header  |  1996-02-07  |  3KB  |  167 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(int i, Vector p)
  17. {
  18.     int    j, k = 0;
  19.  
  20.     wc[i][0] = p[V_W] + p[V_X];
  21.     wc[i][1] = p[V_W] - p[V_X];
  22.     wc[i][2] = p[V_W] + p[V_Y];
  23.     wc[i][3] = p[V_W] - p[V_Y];
  24.     wc[i][4] = p[V_W] + p[V_Z];
  25.     wc[i][5] = p[V_W] - p[V_Z];
  26.     
  27.     for (j = 0; j < 6; j++)
  28.         if (wc[i][j] < 0.0)
  29.             k |= planes[j];
  30.  
  31.     return(k);
  32. }
  33.  
  34. /*
  35.  * clip
  36.  *
  37.  * Clips a 3D line using Homogeneous clipping.
  38.  * Reference: Newman and Sproull
  39.  *
  40.  */
  41. void
  42. clip(register Vector p0, register Vector p1)
  43. {
  44.     float    t, t1, t2, dx, dy, dz, dw;
  45.     int    vx, vy, c1, c2, i;
  46.  
  47.     c1 = MakeEdgeCoords(0, p0);
  48.     c2 = MakeEdgeCoords(1, p1);
  49.  
  50.     if (!(c1 & c2)) {
  51.  
  52.         t1 = 0.0;
  53.         t2 = 1.0;
  54.         for (i = 0; i < 6; i++)
  55.             if (wc[0][i] < 0.0 || wc[1][i] < 0.0) {
  56.                 t = wc[0][i] / (wc[0][i] - wc[1][i]);
  57.                 if (wc[0][i] < 0.0) {
  58.                     if (t > t1) 
  59.                         t1 = t;
  60.                 } else if (t < t2) 
  61.                         t2 = t;
  62.             }
  63.          
  64.          if (t2 >= t1) {
  65.             vdevice.cpVvalid = 1;
  66.             dx = p1[V_X] - p0[V_X];
  67.             dy = p1[V_Y] - p0[V_Y];
  68.             dz = p1[V_Z] - p0[V_Z];
  69.             dw = p1[V_W] - p0[V_W];
  70.             if (t2 != 1.0) {
  71.                 p1[V_X] = p0[V_X] + t2 * dx;
  72.                 p1[V_Y] = p0[V_Y] + t2 * dy;
  73.                 p1[V_Z] = p0[V_Z] + t2 * dz;
  74.                 p1[V_W] = p0[V_W] + t2 * dw;
  75.                 vdevice.cpVvalid = 0;
  76.             }
  77.             if (t1 != 0.0) {
  78.                 p0[V_X] = p0[V_X] + t1 * dx;
  79.                 p0[V_Y] = p0[V_Y] + t1 * dy;
  80.                 p0[V_Z] = p0[V_Z] + t1 * dz;
  81.                 p0[V_W] = p0[V_W] + t1 * dw;
  82.             }
  83.             vdevice.cpVx = WtoVx(p0);
  84.             vdevice.cpVy = WtoVy(p0);
  85.  
  86.             if (vdevice.attr->a.style) {
  87.                 dashline(p0, p1);
  88.                 return;
  89.             }
  90.  
  91.             vx = WtoVx(p1);
  92.             vy = WtoVy(p1);
  93.             (*vdevice.dev.Vdraw)(vx, vy);
  94.             vdevice.cpVx = vx;
  95.             vdevice.cpVy = vy;
  96.         }
  97.     }
  98. }
  99.  
  100.  
  101. /*
  102.  * quickclip
  103.  *
  104.  * A variation on the above that assumes p0 is a valid position in device coords
  105.  *
  106.  */
  107. void
  108. quickclip(register Vector p0, register Vector p1)
  109. {
  110.     register float    t, t1;
  111.     register int    vx, vy, i;
  112.  
  113.     t1 = 1.0;
  114.  
  115.     wc[0][0] = p0[V_W] + p0[V_X];
  116.     wc[0][1] = p0[V_W] - p0[V_X];
  117.     wc[0][2] = p0[V_W] + p0[V_Y];
  118.     wc[0][3] = p0[V_W] - p0[V_Y];
  119.     wc[0][4] = p0[V_W] + p0[V_Z];
  120.     wc[0][5] = p0[V_W] - p0[V_Z];
  121.     wc[1][0] = p1[V_W] + p1[V_X];
  122.     wc[1][1] = p1[V_W] - p1[V_X];
  123.     wc[1][2] = p1[V_W] + p1[V_Y];
  124.     wc[1][3] = p1[V_W] - p1[V_Y];
  125.     wc[1][4] = p1[V_W] + p1[V_Z];
  126.     wc[1][5] = p1[V_W] - p1[V_Z];
  127.  
  128.     for (i = 0; i < 6; i++)
  129.         if (wc[0][i] >= 0.0 && wc[1][i] < 0.0) {
  130.             t = wc[0][i] / (wc[0][i] - wc[1][i]);
  131.             if (t < t1)
  132.                     t1 = t;
  133.         }
  134.      
  135.     vdevice.cpVvalid = 1;
  136.     if (t1 != 1.0) {
  137.         p1[V_X] = p0[V_X] + t1 * (p1[V_X] - p0[V_X]);
  138.         p1[V_Y] = p0[V_Y] + t1 * (p1[V_Y] - p0[V_Y]);
  139.         p1[V_Z] = p0[V_Z] + t1 * (p1[V_Z] - p0[V_Z]);
  140.         p1[V_W] = p0[V_W] + t1 * (p1[V_W] - p0[V_W]);
  141.         vdevice.cpVvalid = 0;
  142.     }
  143.  
  144.     if (vdevice.attr->a.style) {
  145.         dashline(p0, p1);
  146.         return;
  147.     }
  148.  
  149.     vx = WtoVx(p1);
  150.     vy = WtoVy(p1);
  151.  
  152.     (*vdevice.dev.Vdraw)(vx, vy);
  153.     vdevice.cpVx = vx;
  154.     vdevice.cpVy = vy;
  155. }
  156.  
  157. /*
  158.  * clipping
  159.  *
  160.  *     Turns clipping on or off.
  161.  */
  162. void
  163. clipping(int onoff)
  164. {
  165.     vdevice.clipoff = !onoff;
  166. }
  167.