# HG changeset patch # User Matti Hamalainen # Date 1349863355 -10800 # Node ID 200329bb768814064d5fa48ec2f0c1940e37d0d0 # Parent ddb24754a67c51286ae59d0f21a3b973eff03838 Fix the Cohen-Sutherland clipping implementation and add optional compile-time debugging. diff -r ddb24754a67c -r 200329bb7688 dmlineclip.h --- a/dmlineclip.h Wed Oct 10 12:11:48 2012 +0300 +++ b/dmlineclip.h Wed Oct 10 13:02:35 2012 +0300 @@ -1,13 +1,20 @@ +/* Clip line coordinates. Return value: + * = 0 : No clipping needed. + * > 0 : Clipped. Line partially inside the clipping area. + * < 0 : Line completely outside the clipping area. + */ + #ifndef DM_HEADER -#define DM_CLIP_BITS(Q, x, y) \ +#define DM_CLIP_BITS(QB, QX, QY) \ do { \ - Q = 0; \ - if (x < clipX0) Q |= CLIP_TOP; \ + QB = 0; \ + if (QX < clipX0) QB |= CLIP_LEFT; \ else \ - if (x > clipX1) Q |= CLIP_BOTTOM; \ - if (y < clipY0) Q |= CLIP_RIGHT; \ + if (QX > clipX1) QB |= CLIP_RIGHT; \ + \ + if (QY < clipY0) QB |= CLIP_TOP; \ else \ - if (y > clipY1) Q |= CLIP_LEFT; \ + if (QY > clipY1) QB |= CLIP_BOTTOM; \ } while (0) #define xA (*x0) @@ -16,6 +23,11 @@ #define yB (*y1) #endif +#ifdef DM_CLIP_DEBUG +#define CLIPDEB(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__) +#else +#define CLIPDEB(fmt, ...) +#endif int DM_CLIP_FUNC (SDL_Surface *screen, DM_COORD_TYPE *x0, DM_COORD_TYPE *y0, DM_COORD_TYPE *x1, DM_COORD_TYPE *y1) #ifdef DM_HEADER @@ -33,43 +45,55 @@ DM_CLIP_BITS(clipA, xA, yA); DM_CLIP_BITS(clipB, xB, yB); + CLIPDEB("-- clip [%d, %d - %d, %d] --\n", xA, yA, xB, yB); + +#if 1 + // The segment is inside? + if ((clipA | clipB) == 0) + return 0; + // The line segment is outside of the clip region if (clipA & clipB) return -1; - // The segment is inside? - if ((clipA | clipB) == 0) - return 0; - -#if 1 // Cohen-Sutherland clipping method do { const int c = clipA ? clipA : clipB; DM_COORD_TYPE x, y; +#ifdef DM_CLIP_DEBUG + CLIPDEB "CLIP : "); + if (c == clipA) + CLIPDEB("A [%d, %d]\n", xA, yA); + else + CLIPDEB("B [%d, %d]\n", xB, yB); +#endif if (c & CLIP_TOP) { - y = yA + ((clipX0 + xA) * (yB - yA)) / xB - xA; - x = clipX0; + x = xA + ((clipY0 - yA) * (xB - xA)) / (yB - yA); + y = clipY0; + CLIPDEB("TOP : %d, %d\n", x, y); } else if (c & CLIP_BOTTOM) { - y = yA + ((clipX1 - xA)*(yB - yA)) / (xB - xA); - x = clipX1; + x = xA + ((clipY1 - yA) * (xB - xA)) / (yB - yA); + y = clipY1; + CLIPDEB("BOTTOM : %d, %d\n", x, y); } else if (c & CLIP_RIGHT) { - x = xA + ((clipY0 - yA)*(xB - xA)) / (yB - yA); - y = clipY0; + y = yA + ((clipX1 - xA) * (yB - yA)) / (xB - xA); + x = clipX1; + CLIPDEB("RIGHT : %d, %d\n", x, y); } else - if (c & CLIP_LEFT) { - x = xA + ((clipY1 - yA)*(xB - xA)) / (yB - yA); - y = clipY1; + y = yA + ((clipX0 - xA) * (yB - yA)) / xB - xA; + x = clipX0; + CLIPDEB("LEFT : %d, %d\n", x, y); } if (c == clipA) @@ -260,7 +284,7 @@ #undef xB #undef yA #undef yB - +#undef CLIPDEB #endif #undef DM_CLIP_FUNC