freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] anuj-distance-field 5baa2ce 32/93: * src/sdf/ftsdf.c (sdf_co


From: Anuj Verma
Subject: [freetype2] anuj-distance-field 5baa2ce 32/93: * src/sdf/ftsdf.c (sdf_contour_get_min_distance): Use epsilon.
Date: Sun, 2 Aug 2020 07:04:16 -0400 (EDT)

branch: anuj-distance-field
commit 5baa2cefc6e8252b0865951ca4bd3ef969dce9ef
Author: Anuj Verma <anujv@iitbhilai.ac.in>
Commit: anujverma <anujv@iitbhilai.ac.in>

    * src/sdf/ftsdf.c (sdf_contour_get_min_distance): Use epsilon.
---
 [GSoC]ChangeLog | 12 ++++++++++++
 src/sdf/ftsdf.c | 57 +++++++++++++++++++++++++++++++++------------------------
 2 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/[GSoC]ChangeLog b/[GSoC]ChangeLog
index 2f7c96c..15115c9 100644
--- a/[GSoC]ChangeLog
+++ b/[GSoC]ChangeLog
@@ -1,5 +1,17 @@
 2020-07-03  Anuj Verma  <anujv@iitbhilai.ac.in>
 
+       * src/sdf/ftsdf.c (resolve_corner): [Bug] Remove the
+         nearest_point check. Two distances can be same and
+         can give opposite sign, but they may not have a
+         common nearest_point. Also remove distance check
+         because due to precision errors the two distances can
+         be really really close. Therefore use epsilon instead.
+
+       * src/sdf/ftsdf.c (sdf_contour_get_min_distance): Use
+         epsilon for comparing distances.
+
+2020-07-03  Anuj Verma  <anujv@iitbhilai.ac.in>
+
        * src/sdf/ftsdf.c (sdf_shape_dump): Add more info
          to the debug output.
 
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index c0f4e1e..8d8ba8a 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -41,6 +41,11 @@
   /* the shortest distance.                                               */
   #define MAX_NEWTON_STEPS     4
 
+  /* This is the distance in 16.16 which is used for corner resolving. If */
+  /* the difference of two distance is less than `CORNER_CHECK_EPSILON'   */
+  /* then they will be checked for corner if they have ambiguity.         */
+  #define CORNER_CHECK_EPSILON  32
+
   /**************************************************************************
    *
    * macros
@@ -986,39 +991,34 @@
                   SDF_Signed_Distance  sdf2,
                   FT_26D6_Vec          point )
   {
-    FT_16D16_Vec  dist;
+    FT_16D16_Vec  dist1;
+    FT_16D16_Vec  dist2;
 
     FT_16D16      ortho1;
     FT_16D16      ortho2;
 
-    /* if they are not equal return the shorter */
-    if ( sdf1.distance != sdf2.distance )
-      return sdf1.distance < sdf2.distance ?
-             sdf1 : sdf2;
 
     /* if there is not ambiguity in the sign return any */
     if ( sdf1.sign == sdf2.sign )
       return sdf1;
 
-    /* final check: Make sure nearest point is same. If not */
-    /* then return any, it is not the shortest distance.    */
-    if ( sdf1.nearest_point.x != sdf2.nearest_point.x ||
-         sdf1.nearest_point.y != sdf2.nearest_point.y )
-      return sdf1;
+    /* calculate the distance vectors */
+    dist1.x = FT_26D6_16D16( point.x ) - sdf1.nearest_point.x;
+    dist1.y = FT_26D6_16D16( point.y ) - sdf1.nearest_point.y;
 
-    /* calculate the distance vectors, will be same for both */
-    dist.x = sdf1.nearest_point.x - FT_26D6_16D16( point.x );
-    dist.y = sdf1.nearest_point.y - FT_26D6_16D16( point.y );
+    dist2.x = FT_26D6_16D16( point.x ) - sdf2.nearest_point.x;
+    dist2.y = FT_26D6_16D16( point.y ) - sdf2.nearest_point.y;
 
-    FT_Vector_NormLen( &dist );
+    FT_Vector_NormLen( &dist1 );
+    FT_Vector_NormLen( &dist2 );
 
     /* use cross product to find orthogonality */
-    ortho1 = FT_MulFix( sdf1.direction.x, dist.y ) -
-             FT_MulFix( sdf1.direction.y, dist.x );
+    ortho1 = FT_MulFix( sdf1.direction.x, dist1.y ) -
+             FT_MulFix( sdf1.direction.y, dist1.x );
     ortho1 = FT_ABS( ortho1 );
 
-    ortho2 = FT_MulFix( sdf2.direction.x, dist.y ) -
-             FT_MulFix( sdf2.direction.y, dist.x );
+    ortho2 = FT_MulFix( sdf2.direction.x, dist2.y ) -
+             FT_MulFix( sdf2.direction.y, dist2.x );
     ortho2 = FT_ABS( ortho2 );
 
     return ortho1 > ortho2 ? sdf1 : sdf2;
@@ -1700,18 +1700,27 @@
     /* iterate through all the edges manually */
     while ( edge_list.head ) {
       SDF_Signed_Distance  current_dist = max_sdf;
+      FT_16D16             diff;
     
     
       FT_CALL( sdf_edge_get_min_distance( 
                (SDF_Edge*)edge_list.head->data,
                point, &current_dist ) );
 
-      if ( current_dist.distance >= 0 && 
-           current_dist.distance < min_dist.distance )
-        min_dist = current_dist;
-      else if ( current_dist.distance ==
-                min_dist.distance )
-        min_dist = resolve_corner( min_dist, current_dist, point );
+      if ( current_dist.distance >= 0 )
+      {
+        diff = current_dist.distance - min_dist.distance;
+
+
+        if ( FT_ABS(diff ) < CORNER_CHECK_EPSILON )
+          min_dist = resolve_corner( min_dist, current_dist, point );
+        else if ( diff < 0 )
+          min_dist = current_dist;
+      }
+      else
+      {
+        FT_TRACE0(( "sdf_contour_get_min_distance: Overflowed.\n" ));
+      }
     
       edge_list.head = edge_list.head->next;
     }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]