00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <math.h>
00031 
00032 #include "clip.h"
00033 
00034 #define TRUE -1
00035 #define FALSE 0
00036 
00037 typedef enum {
00038         LEFT, RIGHT, BOTTOM, TOP
00039 } edge;
00040 typedef long outcode;
00041 
00042 
00043 
00044 struct LOC_cohen_sutherland_line_clip {
00045         double xmin, xmax, ymin, ymax;
00046 } ;
00047 
00048 void CompOutCode (double x, double y, outcode *code, struct LOC_cohen_sutherland_line_clip *LINK)
00049 {
00050         
00051         *code = 0;
00052         if (y > LINK->ymax)
00053                 *code = 1L << ((long)TOP);
00054         else if (y < LINK->ymin)
00055                 *code = 1L << ((long)BOTTOM);
00056         if (x > LINK->xmax)
00057                 *code |= 1L << ((long)RIGHT);
00058         else if (x < LINK->xmin)
00059                 *code |= 1L << ((long)LEFT);
00060 }
00061 
00062 ClipResult cohen_sutherland_line_clip_i (int *x0_, int *y0_, int *x1_, int *y1_, 
00063                                int xmin_, int xmax_, int ymin_, int ymax_)
00064 {
00065         ClipResult ret;
00066         double x0,y0,x1,y1;
00067         x0 = *x0_;
00068         y0 = *y0_;
00069         x1 = *x1_;
00070         y1 = *y1_;
00071         ret = cohen_sutherland_line_clip_d (&x0, &y0, &x1, &y1, 
00072                                           (double)xmin_, (double)xmax_,
00073                                           (double)ymin_, (double)ymax_);
00074         *x0_ = (int)x0;
00075         *y0_ = (int)y0;
00076         *x1_ = (int)x1;
00077         *y1_ = (int)y1;
00078         return ret;
00079 }
00080 
00100 ClipResult cohen_sutherland_line_clip_d (double *x0, double *y0, double *x1, double *y1, 
00101                                       double xmin_, double xmax_, double ymin_, double ymax_)
00102 {
00103         
00104 
00105         struct LOC_cohen_sutherland_line_clip V;
00106         int accept = FALSE, done = FALSE;
00107         ClipResult clip = NotClipped;
00108         outcode outcode0, outcode1, outcodeOut;
00109         
00110         double x=0., y=0.;
00111         
00112         V.xmin = xmin_;
00113         V.xmax = xmax_;
00114         V.ymin = ymin_;
00115         V.ymax = ymax_;
00116         CompOutCode(*x0, *y0, &outcode0, &V);
00117         CompOutCode(*x1, *y1, &outcode1, &V);
00118         do {
00119                 if (outcode0 == 0 && outcode1 == 0) {   
00120                         accept = TRUE;
00121                         done = TRUE;
00122                 } else if ((outcode0 & outcode1) != 0)
00123                         done = TRUE;
00124                 
00125                 else {
00126                         clip = WasClipped;      
00127                         
00128 
00129                         
00130                         if (outcode0 != 0)
00131                                 outcodeOut = outcode0;
00132                         else
00133                                 outcodeOut = outcode1;
00134                         
00135 
00136                         
00137                         if (((1L << ((long)TOP)) & outcodeOut) != 0) {
00138                                 
00139                                 x = *x0 + (*x1 - *x0) * (V.ymax - *y0) / (*y1 - *y0);
00140                                 y = V.ymax;
00141                         } else if (((1L << ((long)BOTTOM)) & outcodeOut) != 0) {
00142                                 
00143                                 x = *x0 + (*x1 - *x0) * (V.ymin - *y0) / (*y1 - *y0);
00144                                 y = V.ymin;
00145                         } else if (((1L << ((long)RIGHT)) & outcodeOut) != 0) {
00146                                 
00147                                 y = *y0 + (*y1 - *y0) * (V.xmax - *x0) / (*x1 - *x0);
00148                                 x = V.xmax;
00149                         } else if (((1L << ((long)LEFT)) & outcodeOut) != 0) {
00150                                 
00151                                 y = *y0 + (*y1 - *y0) * (V.xmin - *x0) / (*x1 - *x0);
00152                                 x = V.xmin;
00153                         }
00154                         
00155 
00156                         if (outcodeOut == outcode0) {
00157                                 *x0 = x;
00158                                 *y0 = y;
00159                                 CompOutCode(*x0, *y0, &outcode0, &V);
00160                         } else {
00161                                 *x1 = x;
00162                                 *y1 = y;
00163                                 CompOutCode(*x1, *y1, &outcode1, &V);
00164                         }
00165                 }
00166         } while (!done);
00167         return clip;
00168 }