| 1 | greg | 1.1 | #ifndef lint | 
| 2 | schorsch | 2.5 | static const char       RCSid[] = "$Id: clip.c,v 2.4 2003/02/25 02:47:21 greg Exp $"; | 
| 3 | greg | 1.1 | #endif | 
| 4 |  |  | /* | 
| 5 |  |  | *  clip.c - routine to clip 3D line segments to a box. | 
| 6 | greg | 2.3 | */ | 
| 7 |  |  |  | 
| 8 | greg | 2.4 | #include "copyright.h" | 
| 9 | greg | 1.1 |  | 
| 10 | greg | 1.2 | #include  "fvect.h" | 
| 11 |  |  |  | 
| 12 | greg | 1.1 | #include  "plocate.h" | 
| 13 |  |  |  | 
| 14 | greg | 2.2 | #define MAXITER         6       /* maximum possible number of iterations */ | 
| 15 | greg | 1.1 |  | 
| 16 | greg | 2.2 |  | 
| 17 | greg | 2.3 | int | 
| 18 | greg | 1.1 | clip(ep1, ep2, min, max)        /* clip a line segment to a box */ | 
| 19 | schorsch | 2.5 | RREAL  *ep1, *ep2; | 
| 20 | greg | 1.2 | FVECT  min, max; | 
| 21 | greg | 1.1 | { | 
| 22 | greg | 2.2 | int  itlim = MAXITER; | 
| 23 | greg | 1.1 | int  loc1, loc2; | 
| 24 |  |  | int  accept; | 
| 25 | schorsch | 2.5 | RREAL  *dp; | 
| 26 | greg | 1.1 | double  d; | 
| 27 |  |  | register int  i, j; | 
| 28 |  |  |  | 
| 29 |  |  | /* | 
| 30 |  |  | *      The Cohen-Sutherland algorithm is used to determine | 
| 31 |  |  | *  what part (if any) of the given line segment is contained | 
| 32 |  |  | *  in the box specified by the min and max vectors. | 
| 33 |  |  | *      The routine returns non-zero if any segment is left. | 
| 34 |  |  | */ | 
| 35 |  |  |  | 
| 36 |  |  | loc1 = plocate(ep1, min, max); | 
| 37 |  |  | loc2 = plocate(ep2, min, max); | 
| 38 |  |  |  | 
| 39 |  |  | /* check for trivial accept and reject */ | 
| 40 |  |  | /* trivial accept is both points inside */ | 
| 41 |  |  | /* trivial reject is both points to one side */ | 
| 42 |  |  |  | 
| 43 |  |  | while (!((accept = !(loc1 | loc2)) || (loc1 & loc2))) { | 
| 44 |  |  |  | 
| 45 | greg | 2.2 | if (itlim-- <= 0)       /* past theoretical limit? */ | 
| 46 |  |  | return(0);      /* quit fooling around */ | 
| 47 |  |  |  | 
| 48 | greg | 1.1 | if (!loc1) {            /* make sure first point is outside */ | 
| 49 |  |  | dp = ep1; ep1 = ep2; ep2 = dp; | 
| 50 |  |  | i = loc1; loc1 = loc2; loc2 = i; | 
| 51 |  |  | } | 
| 52 |  |  |  | 
| 53 |  |  | for (i = 0; i < 3; i++) {               /* chop segment */ | 
| 54 |  |  |  | 
| 55 |  |  | if (loc1 & position(i) & BELOW) { | 
| 56 |  |  | d = (min[i] - ep1[i])/(ep2[i] - ep1[i]); | 
| 57 |  |  | ep1[i] = min[i]; | 
| 58 |  |  | } else if (loc1 & position(i) & ABOVE) { | 
| 59 |  |  | d = (max[i] - ep1[i])/(ep2[i] - ep1[i]); | 
| 60 |  |  | ep1[i] = max[i]; | 
| 61 |  |  | } else | 
| 62 |  |  | continue; | 
| 63 |  |  |  | 
| 64 |  |  | for (j = 0; j < 3; j++) | 
| 65 |  |  | if (j != i) | 
| 66 |  |  | ep1[j] += (ep2[j] - ep1[j])*d; | 
| 67 |  |  | break; | 
| 68 |  |  | } | 
| 69 |  |  | loc1 = plocate(ep1, min, max); | 
| 70 |  |  | } | 
| 71 |  |  | return(accept); | 
| 72 |  |  | } |