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 }