[sdf] Add function to resolve corner distances. * src/sdf/ftsdf.c (resolve_corner): New function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
diff --git a/ChangeLog b/ChangeLog
index 7abe62d..c64b5f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2020-08-18 Anuj Verma <anujv@iitbhilai.ac.in>
+ [sdf] Add function to resolve corner distances.
+
+ * src/sdf/ftsdf.c (resolve_corner): New function.
+
+2020-08-18 Anuj Verma <anujv@iitbhilai.ac.in>
+
[sdf] Add essential math functions.
* src/sdf/ftsdf.c (cube_root, arc_cos) [!USE_NEWTON_FOR_CONIC]: New
diff --git a/src/sdf/ftsdf.c b/src/sdf/ftsdf.c
index d518d87..2512155 100644
--- a/src/sdf/ftsdf.c
+++ b/src/sdf/ftsdf.c
@@ -1556,4 +1556,108 @@
#endif /* !USE_NEWTON_FOR_CONIC */
+ /*************************************************************************/
+ /*************************************************************************/
+ /** **/
+ /** RASTERIZER **/
+ /** **/
+ /*************************************************************************/
+ /*************************************************************************/
+
+ /**************************************************************************
+ *
+ * @Function:
+ * resolve_corner
+ *
+ * @Description:
+ * At some places on the grid two edges can give opposite directions;
+ * this happens when the closest point is on one of the endpoint. In
+ * that case we need to check the proper sign.
+ *
+ * This can be visualized by an example:
+ *
+ * ```
+ * x
+ *
+ * o
+ * ^ \
+ * / \
+ * / \
+ * (a) / \ (b)
+ * / \
+ * / \
+ * / v
+ * ```
+ *
+ * Suppose `x` is the point whose shortest distance from an arbitrary
+ * contour we want to find out. It is clear that `o` is the nearest
+ * point on the contour. Now to determine the sign we do a cross
+ * product of the shortest distance vector and the edge direction, i.e.,
+ *
+ * ```
+ * => sign = cross(x - o, direction(a))
+ * ```
+ *
+ * Using the right hand thumb rule we can see that the sign will be
+ * positive.
+ *
+ * If we use `b', however, we have
+ *
+ * ```
+ * => sign = cross(x - o, direction(b))
+ * ```
+ *
+ * In this case the sign will be negative. To determine the correct
+ * sign we thus divide the plane in two halves and check which plane the
+ * point lies in.
+ *
+ * ```
+ * |
+ * x |
+ * |
+ * o
+ * ^|\
+ * / | \
+ * / | \
+ * (a) / | \ (b)
+ * / | \
+ * / \
+ * / v
+ * ```
+ *
+ * We can see that `x` lies in the plane of `a`, so we take the sign
+ * determined by `a`. This test can be easily done by calculating the
+ * orthogonality and taking the greater one.
+ *
+ * The orthogonality is simply the sinus of the two vectors (i.e.,
+ * x - o) and the corresponding direction. We efficiently pre-compute
+ * the orthogonality with the corresponding `get_min_distance_`
+ * functions.
+ *
+ * @Input:
+ * sdf1 ::
+ * First signed distance (can be any of `a` or `b`).
+ *
+ * sdf1 ::
+ * Second signed distance (can be any of `a` or `b`).
+ *
+ * @Return:
+ * The correct signed distance, which is computed by using the above
+ * algorithm.
+ *
+ * @Note:
+ * The function does not care about the actual distance, it simply
+ * returns the signed distance which has a larger cross product. As a
+ * consequence, this function should not be used if the two distances
+ * are fairly apart. In that case simply use the signed distance with
+ * a shorter absolute distance.
+ *
+ */
+ static SDF_Signed_Distance
+ resolve_corner( SDF_Signed_Distance sdf1,
+ SDF_Signed_Distance sdf2 )
+ {
+ return FT_ABS( sdf1.cross ) > FT_ABS( sdf2.cross ) ? sdf1 : sdf2;
+ }
+
/* END */