home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / voglw.zip / clip.c < prev    next >
C/C++ Source or Header  |  1997-02-13  |  3KB  |  147 lines

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