changeset 264:200329bb7688

Fix the Cohen-Sutherland clipping implementation and add optional compile-time debugging.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 10 Oct 2012 13:02:35 +0300
parents ddb24754a67c
children 51ba74f7668c
files dmlineclip.h
diffstat 1 files changed, 45 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- 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