changeset 265:51ba74f7668c

Make line clipping floating point only.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 10 Oct 2012 13:28:31 +0300
parents 200329bb7688
children 4ad2b9739c4a
files dmdrawline.h dmlib.h dmline.c dmlineclip.h
diffstat 4 files changed, 49 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/dmdrawline.h	Wed Oct 10 13:02:35 2012 +0300
+++ b/dmdrawline.h	Wed Oct 10 13:28:31 2012 +0300
@@ -5,7 +5,7 @@
  * (C) Copyright 2011-2012 Tecnic Software productions (TNSP)
  */
 
-int DM_DRAWLINE_NAME (SDL_Surface *screen, int x0, int y0, int x1, int y1, const Uint32 col
+int DM_DRAWLINE_NAME (SDL_Surface *screen, DMFloat fx0, DMFloat fy0, DMFloat fx1, DMFloat fy1, const Uint32 col
 #ifdef DM_DRAWLINE_ARGS
     DM_DRAWLINE_ARGS
 #endif
@@ -18,9 +18,11 @@
     const int qpitch = screen->pitch / DM_DRAWLINE_DST_BYTES;
 
     // Clipping
-    if (dmClipLineCoordsInt(screen, &x0, &y0, &x1, &y1) < 0)
+    if (dmClipLineCoordsFloat(screen, &fx0, &fy0, &fx1, &fy1) < 0)
         return -1;
 
+    int x0 = fx0, y0 = fy0, x1 = fx1, y1 = fy1;
+
     // Compute initial deltas
     dx = (x1 - x0) * 2;
     dy = (y1 - y0) * 2;
@@ -58,7 +60,7 @@
     // Continue based on which delta is larger
     if (dx > dy)
     {
-        int afrac = dy - (dx / 2);
+        int afrac = dy - (dx / 2.0);
         while (x0 != x1)
         {
             if (afrac >= 0)
@@ -75,7 +77,7 @@
     }
     else
     {
-        int afrac = dx - (dy / 2);
+        int afrac = dx - (dy / 2.0);
         while (y0 != y1)
         {
             if (afrac >= 0)
--- a/dmlib.h	Wed Oct 10 13:02:35 2012 +0300
+++ b/dmlib.h	Wed Oct 10 13:28:31 2012 +0300
@@ -281,10 +281,6 @@
     CLIP_LEFT    = 8
 };
 
-#define DM_CLIP_FUNC dmClipLineCoordsInt
-#define DM_COORD_TYPE int
-#include "dmlineclip.h"
-
 #define DM_CLIP_FUNC dmClipLineCoordsFloat
 #define DM_COORD_TYPE DMFloat
 #include "dmlineclip.h"
--- a/dmline.c	Wed Oct 10 13:02:35 2012 +0300
+++ b/dmline.c	Wed Oct 10 13:28:31 2012 +0300
@@ -11,10 +11,6 @@
  * > 0  : Clipped. Line partially inside the clipping area.
  * < 0  : Line completely outside the clipping area.
  */
-#define DM_CLIP_FUNC dmClipLineCoordsInt
-#define DM_COORD_TYPE int
-#include "dmlineclip.h"
-
 #define DM_CLIP_FUNC dmClipLineCoordsFloat
 #define DM_COORD_TYPE DMFloat
 #include "dmlineclip.h"
--- a/dmlineclip.h	Wed Oct 10 13:02:35 2012 +0300
+++ b/dmlineclip.h	Wed Oct 10 13:28:31 2012 +0300
@@ -17,10 +17,10 @@
         if (QY > clipY1) QB |= CLIP_BOTTOM;	\
     } while (0)
 
-#define xA (*x0)
-#define xB (*x1)
-#define yA (*y0)
-#define yB (*y1)
+#define xA (fx0)
+#define xB (fx1)
+#define yA (fy0)
+#define yB (fy1)
 #endif
 
 #ifdef DM_CLIP_DEBUG
@@ -39,61 +39,79 @@
         clipY0 = screen->clip_rect.y,
         clipX1 = clipX0 + screen->clip_rect.w - 1,
         clipY1 = clipY0 + screen->clip_rect.h - 1;
-
+    double fx0 = *x0, fy0 = *y0, fx1 = *x1, fy1 = *y1;
     int clipA, clipB;
 
     DM_CLIP_BITS(clipA, xA, yA);
     DM_CLIP_BITS(clipB, xB, yB);
 
-    CLIPDEB("-- clip [%d, %d - %d, %d] --\n", xA, yA, xB, yB);
+    CLIPDEB("-- clip [%1.3f, %1.3f - %1.3f, %1.3f] --\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;
-
     // Cohen-Sutherland clipping method
     do
     {
         const int c = clipA ? clipA : clipB;
         DM_COORD_TYPE x, y;
         
+        // The segment is inside?
+        if ((clipA | clipB) == 0)
+        {
+            *x0 = fx0;
+            *y0 = fy0;
+            *x1 = fx1;
+            *y1 = fy1;
+            return 0;
+        }
+
+        // The line segment is outside of the clip region
+        if (clipA & clipB)
+            return -1;
+
 #ifdef DM_CLIP_DEBUG
         CLIPDEB    "CLIP   : ");
         if (c == clipA)
-            CLIPDEB("A [%d, %d]\n", xA, yA);
+            CLIPDEB("A [%1.3f, %1.3f]\n", xA, yA);
         else
-            CLIPDEB("B [%d, %d]\n", xB, yB);
+            CLIPDEB("B [%1.3f, %1.3f]\n", xB, yB);
 #endif
         if (c & CLIP_TOP)
         {
-            x = xA + ((clipY0 - yA) * (xB - xA)) / (yB - yA);
+            if (yB - yA != 0)
+                x = xA + ((clipY0 - yA) * (xB - xA)) / (yB - yA);
+            else
+                x = xA;
             y = clipY0;
-            CLIPDEB("TOP    : %d, %d\n", x, y);
+            CLIPDEB("TOP    : %1.3f, %1.3f\n", x, y);
         }
         else
         if (c & CLIP_BOTTOM)
         {
-            x = xA + ((clipY1 - yA) * (xB - xA)) / (yB - yA);
+            if (yB - yA != 0)
+                x = xA + ((clipY1 - yA) * (xB - xA)) / (yB - yA);
+            else
+                x = xA;
             y = clipY1;
-            CLIPDEB("BOTTOM : %d, %d\n", x, y);
+            CLIPDEB("BOTTOM : %1.3f, %1.3f\n", x, y);
         }
         else
         if (c & CLIP_RIGHT)
         {
-            y = yA + ((clipX1 - xA) * (yB - yA)) / (xB - xA);
+            if (xB - xA != 0)
+                y = yA + ((clipX1 - xA) * (yB - yA)) / (xB - xA);
+            else
+                y = yA;
             x = clipX1;
-            CLIPDEB("RIGHT  : %d, %d\n", x, y);
+            CLIPDEB("RIGHT  : %1.3f, %1.3f\n", x, y);
         }
         else
         {
-            y = yA + ((clipX0 - xA) * (yB - yA)) / xB - xA;
+            if (xB - xA != 0)
+                y = yA + ((clipX0 - xA) * (yB - yA)) / xB - xA;
+            else
+                y = yA;
             x = clipX0;
-            CLIPDEB("LEFT   : %d, %d\n", x, y);
+            CLIPDEB("LEFT   : %1.3f, %1.3f\n", x, y);
         }
 
         if (c == clipA)
@@ -109,7 +127,7 @@
             DM_CLIP_BITS(clipB, xB, yB);
         }
         
-    } while (clipA | clipB);
+    } while (1);
 #else
     // Buyu-Skala clipping method
     const DM_COORD_TYPE dx = xB - xA;