[PATCH 3/3] d2d1: Implement d2d_cdt_incircle() in a more robust way.

Henri Verbeet hverbeet at codeweavers.com
Tue Oct 6 11:48:23 CDT 2015


Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
 dlls/d2d1/geometry.c | 336 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 327 insertions(+), 9 deletions(-)

diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c
index d80705b..3ed9c86 100644
--- a/dlls/d2d1/geometry.c
+++ b/dlls/d2d1/geometry.c
@@ -86,6 +86,12 @@ struct d2d_fp_two_vec2
     float y[2];
 };
 
+struct d2d_fp_fin
+{
+    float *now, *other;
+    size_t length;
+};
+
 static void d2d_fp_two_sum(float *out, float a, float b)
 {
     float a_virt, a_round, b_virt, b_round;
@@ -107,6 +113,16 @@ static void d2d_fp_fast_two_sum(float *out, float a, float b)
     out[0] = b - b_virt;
 }
 
+static void d2d_fp_two_two_sum(float *out, const float *a, const float *b)
+{
+    float sum[2];
+
+    d2d_fp_two_sum(out, a[0], b[0]);
+    d2d_fp_two_sum(sum, a[1], out[1]);
+    d2d_fp_two_sum(&out[1], sum[0], b[1]);
+    d2d_fp_two_sum(&out[2], sum[1], out[2]);
+}
+
 static void d2d_fp_two_diff_tail(float *out, float a, float b, float x)
 {
     float a_virt, a_round, b_virt, b_round;
@@ -160,6 +176,17 @@ static void d2d_fp_two_product(float *out, float a, float b)
     d2d_fp_two_product_presplit(out, a, b, b_split);
 }
 
+static void d2d_fp_square(float *out, float a)
+{
+    float a_split[2], err1, err2;
+
+    out[1] = a * a;
+    d2d_fp_split(a_split, a);
+    err1 = out[1] - (a_split[1] * a_split[1]);
+    err2 = err1 - ((a_split[1] + a_split[1]) * a_split[0]);
+    out[0] = (a_split[0] * a_split[0]) - err2;
+}
+
 static float d2d_fp_estimate(float *a, size_t len)
 {
     float out = a[0];
@@ -245,6 +272,33 @@ static void d2d_fp_fast_expansion_sum_zeroelim(float *out, size_t *out_len,
     *out_len = out_idx;
 }
 
+static void d2d_fp_scale_expansion_zeroelim(float *out, size_t *out_len, const float *a, size_t a_len, float b)
+{
+    float product[2], sum[2], b_split[2], q[2], a_curr;
+    size_t a_idx, out_idx;
+
+    d2d_fp_split(b_split, b);
+    d2d_fp_two_product_presplit(q, a[0], b, b_split);
+    out_idx = 0;
+    if (q[0] != 0.0f)
+        out[out_idx++] = q[0];
+    for (a_idx = 1; a_idx < a_len; ++a_idx)
+    {
+        a_curr = a[a_idx];
+        d2d_fp_two_product_presplit(product, a_curr, b, b_split);
+        d2d_fp_two_sum(sum, q[1], product[0]);
+        if (sum[0] != 0.0f)
+            out[out_idx++] = sum[0];
+        d2d_fp_fast_two_sum(q, product[1], sum[1]);
+        if (q[0] != 0.0f)
+            out[out_idx++] = q[0];
+    }
+    if (q[1] != 0.0f || !out_idx)
+        out[out_idx++] = q[1];
+
+    *out_len = out_idx;
+}
+
 static void d2d_point_subtract(D2D1_POINT_2F *out,
         const D2D1_POINT_2F *a, const D2D1_POINT_2F *b)
 {
@@ -520,6 +574,153 @@ static BOOL d2d_cdt_leftof(const struct d2d_cdt *cdt, size_t p, const struct d2d
     return d2d_cdt_ccw(cdt, p, d2d_cdt_edge_origin(cdt, e), d2d_cdt_edge_destination(cdt, e)) > 0.0f;
 }
 
+/* |ax ay|
+ * |bx by| */
+static void d2d_fp_four_det2x2(float *out, float ax, float ay, float bx, float by)
+{
+    float axby[2], aybx[2];
+
+    d2d_fp_two_product(axby, ax, by);
+    d2d_fp_two_product(aybx, ay, bx);
+    d2d_fp_two_two_diff(out, axby, aybx);
+}
+
+/* (a->x² + a->y²) * det2x2 */
+static void d2d_fp_sub_det3x3(float *out, size_t *out_len, const struct d2d_fp_two_vec2 *a, const float *det2x2)
+{
+    size_t axd_len, ayd_len, axxd_len, ayyd_len;
+    float axd[8], ayd[8], axxd[16], ayyd[16];
+
+    d2d_fp_scale_expansion_zeroelim(axd, &axd_len, det2x2, 4, a->x[1]);
+    d2d_fp_scale_expansion_zeroelim(axxd, &axxd_len, axd, axd_len, a->x[1]);
+    d2d_fp_scale_expansion_zeroelim(ayd, &ayd_len, det2x2, 4, a->y[1]);
+    d2d_fp_scale_expansion_zeroelim(ayyd, &ayyd_len, ayd, ayd_len, a->y[1]);
+    d2d_fp_fast_expansion_sum_zeroelim(out, out_len, axxd, axxd_len, ayyd, ayyd_len);
+}
+
+/* det_abt = det_ab * c[0]
+ * fin += c[0] * (az * b - bz * a + c[1] * det_ab * 2.0f) */
+static void d2d_cdt_incircle_refine1(struct d2d_fp_fin *fin, float *det_abt, size_t *det_abt_len,
+        const float *det_ab, float a, const float *az, float b, const float *bz, const float *c)
+{
+    size_t temp48_len, temp32_len, temp16a_len, temp16b_len, temp16c_len, temp8_len;
+    float temp48[48], temp32[32], temp16a[16], temp16b[16], temp16c[16], temp8[8];
+    float *swap;
+
+    d2d_fp_scale_expansion_zeroelim(det_abt, det_abt_len, det_ab, 4, c[0]);
+    d2d_fp_scale_expansion_zeroelim(temp16a, &temp16a_len, det_abt, *det_abt_len, 2.0f * c[1]);
+    d2d_fp_scale_expansion_zeroelim(temp8, &temp8_len, az, 4, c[0]);
+    d2d_fp_scale_expansion_zeroelim(temp16b, &temp16b_len, temp8, temp8_len, b);
+    d2d_fp_scale_expansion_zeroelim(temp8, &temp8_len, bz, 4, c[0]);
+    d2d_fp_scale_expansion_zeroelim(temp16c, &temp16c_len, temp8, temp8_len, -a);
+    d2d_fp_fast_expansion_sum_zeroelim(temp32, &temp32_len, temp16a, temp16a_len, temp16b, temp16b_len);
+    d2d_fp_fast_expansion_sum_zeroelim(temp48, &temp48_len, temp16c, temp16c_len, temp32, temp32_len);
+    d2d_fp_fast_expansion_sum_zeroelim(fin->other, &fin->length, fin->now, fin->length, temp48, temp48_len);
+    swap = fin->now; fin->now = fin->other; fin->other = swap;
+}
+
+static void d2d_cdt_incircle_refine2(struct d2d_fp_fin *fin, const struct d2d_fp_two_vec2 *a,
+        const struct d2d_fp_two_vec2 *b, const float *bz, const struct d2d_fp_two_vec2 *c, const float *cz,
+        const float *axt_det_bc, size_t axt_det_bc_len, const float *ayt_det_bc, size_t ayt_det_bc_len)
+{
+    size_t temp64_len, temp48_len, temp32a_len, temp32b_len, temp16a_len, temp16b_len, temp8_len;
+    float temp64[64], temp48[48], temp32a[32], temp32b[32], temp16a[16], temp16b[16], temp8[8];
+    float bct[8], bctt[4], temp4a[4], temp4b[4], temp2a[2], temp2b[2];
+    size_t bct_len, bctt_len;
+    float *swap;
+
+    /* bct = (b->x[0] * c->y[1] + b->x[1] * c->y[0]) - (c->x[0] * b->y[1] + c->x[1] * b->y[0]) */
+    /* bctt = b->x[0] * c->y[0] + c->x[0] * b->y[0] */
+    if (b->x[0] != 0.0f || b->y[0] != 0.0f || c->x[0] != 0.0f || c->y[0] != 0.0f)
+    {
+        d2d_fp_two_product(temp2a, b->x[0], c->y[1]);
+        d2d_fp_two_product(temp2b, b->x[1], c->y[0]);
+        d2d_fp_two_two_sum(temp4a, temp2a, temp2b);
+        d2d_fp_two_product(temp2a, c->x[0], -b->y[1]);
+        d2d_fp_two_product(temp2b, c->x[1], -b->y[0]);
+        d2d_fp_two_two_sum(temp4b, temp2a, temp2b);
+        d2d_fp_fast_expansion_sum_zeroelim(bct, &bct_len, temp4a, 4, temp4b, 4);
+
+        d2d_fp_two_product(temp2a, b->x[0], c->y[0]);
+        d2d_fp_two_product(temp2b, c->x[0], b->y[0]);
+        d2d_fp_two_two_diff(bctt, temp2a, temp2b);
+        bctt_len = 4;
+    }
+    else
+    {
+        bct[0] = 0.0f;
+        bct_len = 1;
+        bctt[0] = 0.0f;
+        bctt_len = 1;
+    }
+
+    if (a->x[0] != 0.0f)
+    {
+        size_t axt_bct_len, axt_bctt_len;
+        float axt_bct[16], axt_bctt[8];
+
+        /* fin += a->x[0] * (axt_det_bc + bct * 2.0f * a->x[1]) */
+        d2d_fp_scale_expansion_zeroelim(temp16a, &temp16a_len, axt_det_bc, axt_det_bc_len, a->x[0]);
+        d2d_fp_scale_expansion_zeroelim(axt_bct, &axt_bct_len, bct, bct_len, a->x[0]);
+        d2d_fp_scale_expansion_zeroelim(temp32a, &temp32a_len, axt_bct, axt_bct_len, 2.0f * a->x[1]);
+        d2d_fp_fast_expansion_sum_zeroelim(temp48, &temp48_len, temp16a, temp16a_len, temp32a, temp32a_len);
+        d2d_fp_fast_expansion_sum_zeroelim(fin->other, &fin->length, fin->now, fin->length, temp48, temp48_len);
+        swap = fin->now; fin->now = fin->other; fin->other = swap;
+
+        if (b->y[0] != 0.0f)
+        {
+            /* fin += a->x[0] * cz * b->y[0] */
+            d2d_fp_scale_expansion_zeroelim(temp8, &temp8_len, cz, 4, a->x[0]);
+            d2d_fp_scale_expansion_zeroelim(temp16a, &temp16a_len, temp8, temp8_len, b->y[0]);
+            d2d_fp_fast_expansion_sum_zeroelim(fin->other, &fin->length, fin->now, fin->length, temp16a, temp16a_len);
+            swap = fin->now; fin->now = fin->other; fin->other = swap;
+        }
+
+        if (c->y[0] != 0.0f)
+        {
+            /* fin -= a->x[0] * bz * c->y[0] */
+            d2d_fp_scale_expansion_zeroelim(temp8, &temp8_len, bz, 4, -a->x[0]);
+            d2d_fp_scale_expansion_zeroelim(temp16a, &temp16a_len, temp8, temp8_len, c->y[0]);
+            d2d_fp_fast_expansion_sum_zeroelim(fin->other, &fin->length, fin->now, fin->length, temp16a, temp16a_len);
+            swap = fin->now; fin->now = fin->other; fin->other = swap;
+        }
+
+        /* fin += a->x[0] * (bct * a->x[0] + bctt * (2.0f * a->x[1] + a->x[0])) */
+        d2d_fp_scale_expansion_zeroelim(temp32a, &temp32a_len, axt_bct, axt_bct_len, a->x[0]);
+        d2d_fp_scale_expansion_zeroelim(axt_bctt, &axt_bctt_len, bctt, bctt_len, a->x[0]);
+        d2d_fp_scale_expansion_zeroelim(temp16a, &temp16a_len, axt_bctt, axt_bctt_len, 2.0f * a->x[1]);
+        d2d_fp_scale_expansion_zeroelim(temp16b, &temp16b_len, axt_bctt, axt_bctt_len, a->x[0]);
+        d2d_fp_fast_expansion_sum_zeroelim(temp32b, &temp32b_len, temp16a, temp16a_len, temp16b, temp16b_len);
+        d2d_fp_fast_expansion_sum_zeroelim(temp64, &temp64_len, temp32a, temp32a_len, temp32b, temp32b_len);
+        d2d_fp_fast_expansion_sum_zeroelim(fin->other, &fin->length, fin->now, fin->length, temp64, temp64_len);
+        swap = fin->now; fin->now = fin->other; fin->other = swap;
+    }
+
+    if (a->y[0] != 0.0f)
+    {
+        size_t ayt_bct_len, ayt_bctt_len;
+        float ayt_bct[16], ayt_bctt[8];
+
+        /* fin += a->y[0] * (ayt_det_bc + bct * 2.0f * a->y[1]) */
+        d2d_fp_scale_expansion_zeroelim(temp16a, &temp16a_len, ayt_det_bc, ayt_det_bc_len, a->y[0]);
+        d2d_fp_scale_expansion_zeroelim(ayt_bct, &ayt_bct_len, bct, bct_len, a->y[0]);
+        d2d_fp_scale_expansion_zeroelim(temp32a, &temp32a_len, ayt_bct, ayt_bct_len, 2.0f * a->y[1]);
+        d2d_fp_fast_expansion_sum_zeroelim(temp48, &temp48_len, temp16a, temp16a_len, temp32a, temp32a_len);
+        d2d_fp_fast_expansion_sum_zeroelim(fin->other, &fin->length, fin->now, fin->length, temp48, temp48_len);
+        swap = fin->now; fin->now = fin->other; fin->other = swap;
+
+        /* fin += a->y[0] * (bct * a->y[0] + bctt * (2.0f * a->y[1] + a->y[0])) */
+        d2d_fp_scale_expansion_zeroelim(temp32a, &temp32a_len, ayt_bct, ayt_bct_len, a->y[0]);
+        d2d_fp_scale_expansion_zeroelim(ayt_bctt, &ayt_bctt_len, bctt, bctt_len, a->y[0]);
+        d2d_fp_scale_expansion_zeroelim(temp16a, &temp16a_len, ayt_bctt, ayt_bctt_len, 2.0f * a->y[1]);
+        d2d_fp_scale_expansion_zeroelim(temp16b, &temp16b_len, ayt_bctt, ayt_bctt_len, a->y[0]);
+        d2d_fp_fast_expansion_sum_zeroelim(temp32b, &temp32b_len, temp16a, temp16a_len, temp16b, temp16b_len);
+        d2d_fp_fast_expansion_sum_zeroelim(temp64, &temp64_len, temp32a, temp32a_len, temp32b, temp32b_len);
+        d2d_fp_fast_expansion_sum_zeroelim(fin->other, &fin->length, fin->now, fin->length, temp64, temp64_len);
+        swap = fin->now; fin->now = fin->other; fin->other = swap;
+    }
+}
+
 /* Determine if point D is inside or outside the circle defined by points A,
  * B, C. As explained in the paper by Guibas and Stolfi, this is equivalent to
  * calculating the signed volume of the tetrahedron defined by projecting the
@@ -535,21 +736,138 @@ static BOOL d2d_cdt_leftof(const struct d2d_cdt *cdt, size_t p, const struct d2d
  *
  * |λ(A-D)|
  * |λ(B-D)| > 0
- * |λ(C-D)| */
+ * |λ(C-D)|
+ *
+ * This implementation is based on the paper "Adaptive Precision
+ * Floating-Point Arithmetic and Fast Robust Geometric Predicates" and
+ * associated (Public Domain) code by Jonathan Richard Shewchuk. */
 static BOOL d2d_cdt_incircle(const struct d2d_cdt *cdt, size_t a, size_t b, size_t c, size_t d)
 {
+    static const float err_bound_result = (3.0f + 8.0f * D2D_FP_EPS) * D2D_FP_EPS;
+    static const float err_bound_a = (10.0f + 96.0f * D2D_FP_EPS) * D2D_FP_EPS;
+    static const float err_bound_b = (4.0f + 48.0f * D2D_FP_EPS) * D2D_FP_EPS;
+    static const float err_bound_c = (44.0f + 576.0f * D2D_FP_EPS) * D2D_FP_EPS * D2D_FP_EPS;
+
+    size_t axt_det_bc_len, ayt_det_bc_len, bxt_det_ca_len, byt_det_ca_len, cxt_det_ab_len, cyt_det_ab_len;
+    float axt_det_bc[8], ayt_det_bc[8], bxt_det_ca[8], byt_det_ca[8], cxt_det_ab[8], cyt_det_ab[8];
+    float fin1[1152], fin2[1152], temp64[64], sub_det_a[32], sub_det_b[32], sub_det_c[32];
+    float det_bc[4], det_ca[4], det_ab[4], daz[4], dbz[4], dcz[4], temp2a[2], temp2b[2];
+    size_t temp64_len, sub_det_a_len, sub_det_b_len, sub_det_c_len;
+    float dbxdcy, dbydcx, dcxday, dcydax, daxdby, daydbx;
     const D2D1_POINT_2F *p = cdt->vertices;
-    const struct
+    struct d2d_fp_two_vec2 da, db, dc;
+    float permanent, err_bound, det;
+    struct d2d_fp_fin fin;
+
+    da.x[1] = p[a].x - p[d].x;
+    da.y[1] = p[a].y - p[d].y;
+    db.x[1] = p[b].x - p[d].x;
+    db.y[1] = p[b].y - p[d].y;
+    dc.x[1] = p[c].x - p[d].x;
+    dc.y[1] = p[c].y - p[d].y;
+
+    daz[3] = da.x[1] * da.x[1] + da.y[1] * da.y[1];
+    dbxdcy = db.x[1] * dc.y[1];
+    dbydcx = db.y[1] * dc.x[1];
+
+    dbz[3] = db.x[1] * db.x[1] + db.y[1] * db.y[1];
+    dcxday = dc.x[1] * da.y[1];
+    dcydax = dc.y[1] * da.x[1];
+
+    dcz[3] = dc.x[1] * dc.x[1] + dc.y[1] * dc.y[1];
+    daxdby = da.x[1] * db.y[1];
+    daydbx = da.y[1] * db.x[1];
+
+    det = daz[3] * (dbxdcy - dbydcx) + dbz[3] * (dcxday - dcydax) + dcz[3] * (daxdby - daydbx);
+    permanent = daz[3] * (fabsf(dbxdcy) + fabsf(dbydcx))
+            + dbz[3] * (fabsf(dcxday) + fabsf(dcydax))
+            + dcz[3] * (fabsf(daxdby) + fabsf(daydbx));
+    err_bound = err_bound_a * permanent;
+    if (det > err_bound || -det > err_bound)
+        return det > 0.0f;
+
+    fin.now = fin1;
+    fin.other = fin2;
+
+    d2d_fp_four_det2x2(det_bc, db.x[1], db.y[1], dc.x[1], dc.y[1]);
+    d2d_fp_sub_det3x3(sub_det_a, &sub_det_a_len, &da, det_bc);
+
+    d2d_fp_four_det2x2(det_ca, dc.x[1], dc.y[1], da.x[1], da.y[1]);
+    d2d_fp_sub_det3x3(sub_det_b, &sub_det_b_len, &db, det_ca);
+
+    d2d_fp_four_det2x2(det_ab, da.x[1], da.y[1], db.x[1], db.y[1]);
+    d2d_fp_sub_det3x3(sub_det_c, &sub_det_c_len, &dc, det_ab);
+
+    d2d_fp_fast_expansion_sum_zeroelim(temp64, &temp64_len, sub_det_a, sub_det_a_len, sub_det_b, sub_det_b_len);
+    d2d_fp_fast_expansion_sum_zeroelim(fin.now, &fin.length, temp64, temp64_len, sub_det_c, sub_det_c_len);
+    det = d2d_fp_estimate(fin.now, fin.length);
+    err_bound = err_bound_b * permanent;
+    if (det >= err_bound || -det >= err_bound)
+        return det > 0.0f;
+
+    d2d_fp_two_diff_tail(&da.x[0], p[a].x, p[d].x, da.x[1]);
+    d2d_fp_two_diff_tail(&da.y[0], p[a].y, p[d].y, da.y[1]);
+    d2d_fp_two_diff_tail(&db.x[0], p[b].x, p[d].x, db.x[1]);
+    d2d_fp_two_diff_tail(&db.y[0], p[b].y, p[d].y, db.y[1]);
+    d2d_fp_two_diff_tail(&dc.x[0], p[c].x, p[d].x, dc.x[1]);
+    d2d_fp_two_diff_tail(&dc.y[0], p[c].y, p[d].y, dc.y[1]);
+    if (da.x[0] == 0.0f && db.x[0] == 0.0f && dc.x[0] == 0.0f
+            && da.y[0] == 0.0f && db.y[0] == 0.0f && dc.y[0] == 0.0f)
+        return det > 0.0f;
+
+    err_bound = err_bound_c * permanent + err_bound_result * fabsf(det);
+    det += (daz[3] * ((db.x[1] * dc.y[0] + dc.y[1] * db.x[0]) - (db.y[1] * dc.x[0] + dc.x[1] * db.y[0]))
+            + 2.0f * (da.x[1] * da.x[0] + da.y[1] * da.y[0]) * (db.x[1] * dc.y[1] - db.y[1] * dc.x[1]))
+            + (dbz[3] * ((dc.x[1] * da.y[0] + da.y[1] * dc.x[0]) - (dc.y[1] * da.x[0] + da.x[1] * dc.y[0]))
+            + 2.0f * (db.x[1] * db.x[0] + db.y[1] * db.y[0]) * (dc.x[1] * da.y[1] - dc.y[1] * da.x[1]))
+            + (dcz[3] * ((da.x[1] * db.y[0] + db.y[1] * da.x[0]) - (da.y[1] * db.x[0] + db.x[1] * da.y[0]))
+            + 2.0f * (dc.x[1] * dc.x[0] + dc.y[1] * dc.y[0]) * (da.x[1] * db.y[1] - da.y[1] * db.x[1]));
+    if (det >= err_bound || -det >= err_bound)
+        return det > 0.0f;
+
+    if (db.x[0] != 0.0f || db.y[0] != 0.0f || dc.x[0] != 0.0f || dc.y[0] != 0.0f)
+    {
+        d2d_fp_square(temp2a, da.x[1]);
+        d2d_fp_square(temp2b, da.y[1]);
+        d2d_fp_two_two_sum(daz, temp2a, temp2b);
+    }
+    if (dc.x[0] != 0.0f || dc.y[0] != 0.0f || da.x[0] != 0.0f || da.y[0] != 0.0f)
+    {
+        d2d_fp_square(temp2a, db.x[1]);
+        d2d_fp_square(temp2b, db.y[1]);
+        d2d_fp_two_two_sum(dbz, temp2a, temp2b);
+    }
+    if (da.x[0] != 0.0f || da.y[0] != 0.0f || db.x[0] != 0.0f || db.y[0] != 0.0f)
     {
-        double x, y;
+        d2d_fp_square(temp2a, dc.x[1]);
+        d2d_fp_square(temp2b, dc.y[1]);
+        d2d_fp_two_two_sum(dcz, temp2a, temp2b);
     }
-    da = {p[a].x - p[d].x, p[a].y - p[d].y},
-    db = {p[b].x - p[d].x, p[b].y - p[d].y},
-    dc = {p[c].x - p[d].x, p[c].y - p[d].y};
 
-    return (da.x * da.x + da.y * da.y) * (db.x * dc.y - db.y * dc.x)
-            + (db.x * db.x + db.y * db.y) * (dc.x * da.y - dc.y * da.x)
-            + (dc.x * dc.x + dc.y * dc.y) * (da.x * db.y - da.y * db.x) > 0.0;
+    if (da.x[0] != 0.0f)
+        d2d_cdt_incircle_refine1(&fin, axt_det_bc, &axt_det_bc_len, det_bc, dc.y[1], dcz, db.y[1], dbz, da.x);
+    if (da.y[0] != 0.0f)
+        d2d_cdt_incircle_refine1(&fin, ayt_det_bc, &ayt_det_bc_len, det_bc, db.x[1], dbz, dc.x[1], dcz, da.y);
+    if (db.x[0] != 0.0f)
+        d2d_cdt_incircle_refine1(&fin, bxt_det_ca, &bxt_det_ca_len, det_ca, da.y[1], daz, dc.y[1], dcz, db.x);
+    if (db.y[0] != 0.0f)
+        d2d_cdt_incircle_refine1(&fin, byt_det_ca, &byt_det_ca_len, det_ca, dc.x[1], dcz, da.x[1], daz, db.y);
+    if (dc.x[0] != 0.0f)
+        d2d_cdt_incircle_refine1(&fin, cxt_det_ab, &cxt_det_ab_len, det_ab, db.y[1], dbz, da.y[1], daz, dc.x);
+    if (dc.y[0] != 0.0f)
+        d2d_cdt_incircle_refine1(&fin, cyt_det_ab, &cyt_det_ab_len, det_ab, da.x[1], daz, db.x[1], dbz, dc.y);
+
+    if (da.x[0] != 0.0f || da.y[0] != 0.0f)
+        d2d_cdt_incircle_refine2(&fin, &da, &db, dbz, &dc, dcz,
+                axt_det_bc, axt_det_bc_len, ayt_det_bc, ayt_det_bc_len);
+    if (db.x[0] != 0.0f || db.y[0] != 0.0f)
+        d2d_cdt_incircle_refine2(&fin, &db, &dc, dcz, &da, daz,
+                bxt_det_ca, bxt_det_ca_len, byt_det_ca, byt_det_ca_len);
+    if (dc.x[0] != 0.0f || dc.y[0] != 0.0f)
+        d2d_cdt_incircle_refine2(&fin, &dc, &da, daz, &db, dbz,
+                cxt_det_ab, cxt_det_ab_len, cyt_det_ab, cyt_det_ab_len);
+
+    return fin.now[fin.length - 1] > 0.0f;
 }
 
 static void d2d_cdt_splice(const struct d2d_cdt *cdt, const struct d2d_cdt_edge_ref *a,
-- 
2.1.4




More information about the wine-patches mailing list