summaryrefslogtreecommitdiff
path: root/sql/gcalc_slicescan.cc
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2011-10-16 19:55:37 +0500
committerAlexey Botchkov <holyfoot@askmonty.org>2011-10-16 19:55:37 +0500
commit248f2da679281c2b35a1719d830b6f0db4d791ac (patch)
tree2189c3819572c6fa8e8d383a7fde7bf108f9e359 /sql/gcalc_slicescan.cc
parent486df97986d839b7ad24a6c36ad6ca43875312e6 (diff)
downloadmariadb-git-248f2da679281c2b35a1719d830b6f0db4d791ac.tar.gz
GIS code cleanup.
Diffstat (limited to 'sql/gcalc_slicescan.cc')
-rw-r--r--sql/gcalc_slicescan.cc840
1 files changed, 426 insertions, 414 deletions
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
index 0a7bbde16d1..03c77163f49 100644
--- a/sql/gcalc_slicescan.cc
+++ b/sql/gcalc_slicescan.cc
@@ -40,6 +40,10 @@ typedef int (*sc_compare_func)(const void*, const void*);
#include "plistsort.c"
+#define GCALC_COORD_MINUS 0x80000000
+#define FIRST_DIGIT(d) ((d) & 0x7FFFFFFF)
+#define GCALC_SIGN(d) ((d) & 0x80000000)
+
static Gcalc_scan_iterator::point *eq_sp(const Gcalc_heap::Info *pi)
{
GCALC_DBUG_ASSERT(pi->type == Gcalc_heap::nt_eq_node);
@@ -97,8 +101,8 @@ const char *gcalc_ev_name(int ev)
static int gcalc_pi_str(char *str, const Gcalc_heap::Info *pi, const char *postfix)
{
return sprintf(str, "%s %d %d | %s %d %d%s",
- pi->ix.sign ? "-":"", pi->ix.digits[0],pi->ix.digits[1],
- pi->iy.sign ? "-":"", pi->iy.digits[0],pi->iy.digits[1],
+ GCALC_SIGN(pi->ix[0]) ? "-":"", FIRST_DIGIT(pi->ix[0]),pi->ix[1],
+ GCALC_SIGN(pi->iy[0]) ? "-":"", FIRST_DIGIT(pi->iy[0]),pi->iy[1],
postfix);
}
@@ -274,264 +278,327 @@ void Gcalc_dyn_list::reset()
/* Internal coordinate operations implementations */
-void Gcalc_internal_coord::set_zero()
+void gcalc_set_zero(Gcalc_internal_coord *d, int d_len)
{
- int n_res= 0;
do
{
- digits[n_res++]= 0;
- } while (n_res < n_digits);
- sign= 0;
+ d[--d_len]= 0;
+ } while (d_len);
}
-int Gcalc_internal_coord::is_zero() const
+int gcalc_is_zero(const Gcalc_internal_coord *d, int d_len)
{
- int n_res= 0;
do
{
- if (digits[n_res++] != 0)
+ if (d[--d_len] != 0)
return 0;
- } while (n_res < n_digits);
+ } while (d_len);
return 1;
}
#ifdef GCALC_CHECK_WITH_FLOAT
-double *Gcalc_internal_coord::coord_extent= NULL;
+static double *gcalc_coord_extent= NULL;
-long double Gcalc_internal_coord::get_double() const
+long double gcalc_get_double(const Gcalc_internal_coord *d, int d_len)
{
int n= 1;
- long double res= (long double) digits[0];
+ long double res= (long double) FIRST_DIGIT(d[0]);
do
{
res*= (long double) GCALC_DIG_BASE;
- res+= (long double) digits[n];
- } while(++n < n_digits);
+ res+= (long double) d[n];
+ } while(++n < d_len);
n= 0;
do
{
- if ((n & 1) && coord_extent)
- res/= *coord_extent;
- } while(++n < n_digits);
+ if ((n & 1) && gcalc_coord_extent)
+ res/= *gcalc_coord_extent;
+ } while(++n < d_len);
- if (sign)
+ if (GCALC_SIGN(d[0]))
res*= -1.0;
return res;
}
#endif /*GCALC_CHECK_WITH_FLOAT*/
-static void do_add(Gcalc_internal_coord *result,
+static void do_add(Gcalc_internal_coord *result, int result_len,
const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b)
{
- GCALC_DBUG_ASSERT(a->n_digits == b->n_digits);
- GCALC_DBUG_ASSERT(a->n_digits == result->n_digits);
- int n_digit= a->n_digits-1;
+ int n_digit= result_len-1;
gcalc_digit_t carry= 0;
do
{
- if ((result->digits[n_digit]=
- a->digits[n_digit] + b->digits[n_digit] + carry) >= GCALC_DIG_BASE)
+ if ((result[n_digit]=
+ a[n_digit] + b[n_digit] + carry) >= GCALC_DIG_BASE)
{
carry= 1;
- result->digits[n_digit]-= GCALC_DIG_BASE;
+ result[n_digit]-= GCALC_DIG_BASE;
}
else
carry= 0;
} while (--n_digit);
- result->digits[0]= a->digits[0] + b->digits[0] + carry;
- GCALC_DBUG_ASSERT(result->digits[0] < GCALC_DIG_BASE);
- result->sign= a->sign;
+
+ result[0]= (a[0] + FIRST_DIGIT(b[0]) + carry);
+
+ GCALC_DBUG_ASSERT(FIRST_DIGIT(result[0]) < GCALC_DIG_BASE);
}
-static void do_sub(Gcalc_internal_coord *result,
+static void do_sub(Gcalc_internal_coord *result, int result_len,
const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b)
{
- GCALC_DBUG_ASSERT(a->n_digits == b->n_digits);
- GCALC_DBUG_ASSERT(a->n_digits == result->n_digits);
- int n_digit= a->n_digits-1;
+ int n_digit= result_len-1;
gcalc_digit_t carry= 0;
+ gcalc_digit_t cur_b, cur_a;
do
{
- if ((result->digits[n_digit]=
- a->digits[n_digit] - b->digits[n_digit] - carry) < 0)
+ cur_b= b[n_digit] + carry;
+ cur_a= a[n_digit];
+ if (cur_a < cur_b)
{
carry= 1;
- result->digits[n_digit]+= GCALC_DIG_BASE;
+ result[n_digit]= (GCALC_DIG_BASE - cur_b) + cur_a;
}
else
+ {
carry= 0;
- } while (n_digit--);
- GCALC_DBUG_ASSERT(carry == 0);
- if (a->sign && result->is_zero())
- result->sign= 0;
- else
- result->sign= a->sign;
+ result[n_digit]= cur_a - cur_b;
+ }
+ } while (--n_digit);
+
+
+ result[0]= a[0] - FIRST_DIGIT(b[0]) - carry;
+
+ GCALC_DBUG_ASSERT(FIRST_DIGIT(a[0]) >= FIRST_DIGIT(b[0]) + carry);
+ GCALC_DBUG_ASSERT(!gcalc_is_zero(result, result_len));
}
+/*
+static void do_sub(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a,
+ const Gcalc_internal_coord *b)
+{
+ int n_digit= result_len-1;
+ gcalc_digit_t carry= 0;
+ do
+ {
+ if ((result[n_digit]= a[n_digit] - b[n_digit] - carry) < 0)
+ {
+ carry= 1;
+ result[n_digit]+= GCALC_DIG_BASE;
+ }
+ else
+ carry= 0;
+ } while (--n_digit);
+
+
+ result[0]= a[0] - FIRST_DIGIT(b[0]) - carry;
+
+ GCALC_DBUG_ASSERT(FIRST_DIGIT(a[0]) - FIRST_DIGIT(b[0]) - carry >= 0);
+ GCALC_DBUG_ASSERT(!gcalc_is_zero(result, result_len));
+}
+*/
static int do_cmp(const Gcalc_internal_coord *a,
- const Gcalc_internal_coord *b)
+ const Gcalc_internal_coord *b, int len)
{
- GCALC_DBUG_ASSERT(a->n_digits == b->n_digits);
- int n_digit= 0;
+ int n_digit= 1;
+
+ if ((FIRST_DIGIT(a[0]) != FIRST_DIGIT(b[0])))
+ return FIRST_DIGIT(a[0]) > FIRST_DIGIT(b[0]) ? 1 : -1;
do
{
- gcalc_digit_t d= a->digits[n_digit] - b->digits[n_digit];
- if (d > 0)
- return 1;
- if (d < 0)
- return -1;
- n_digit++;
- } while (n_digit < a->n_digits);
+ if ((a[n_digit] != b[n_digit]))
+ return a[n_digit] > b[n_digit] ? 1 : -1;
+ } while (++n_digit < len);
return 0;
}
#ifdef GCALC_CHECK_WITH_FLOAT
-static int de_check(long double a, long double b)
+static int de_weak_check(long double a, long double b, long double ex)
{
long double d= a - b;
- if (d < (long double) 1e-10 && d > (long double) -1e-10)
+ if (d < ex && d > -ex)
return 1;
d/= fabsl(a) + fabsl(b);
- if (d < (long double) 1e-10 && d > (long double) -1e-10)
+ if (d < ex && d > -ex)
return 1;
return 0;
}
+
+static int de_check(long double a, long double b)
+{
+ return de_weak_check(a, b, (long double) 1e-10);
+}
#endif /*GCALC_CHECK_WITH_FLOAT*/
-void gcalc_mul_coord(Gcalc_internal_coord *result,
- const Gcalc_internal_coord *a,
- const Gcalc_internal_coord *b)
+void gcalc_mul_coord(Gcalc_internal_coord *result, int result_len,
+ const Gcalc_internal_coord *a, int a_len,
+ const Gcalc_internal_coord *b, int b_len)
{
- GCALC_DBUG_ASSERT(result->n_digits == a->n_digits + b->n_digits);
+ GCALC_DBUG_ASSERT(result_len == a_len + b_len);
+ GCALC_DBUG_ASSERT(a_len >= b_len);
int n_a, n_b, n_res;
gcalc_digit_t carry= 0;
- result->set_zero();
- if (a->is_zero() || b->is_zero())
- return;
+ gcalc_set_zero(result, result_len);
- n_a= a->n_digits - 1;
+ n_a= a_len - 1;
do
{
- n_b= b->n_digits - 1;
+ gcalc_coord2 cur_a= n_a ? a[n_a] : FIRST_DIGIT(a[0]);
+ n_b= b_len - 1;
do
{
- gcalc_coord2 mul= ((gcalc_coord2) a->digits[n_a]) * b->digits[n_b] +
- carry + result->digits[n_a + n_b + 1];
- result->digits[n_a + n_b + 1]= mul % GCALC_DIG_BASE;
+ gcalc_coord2 cur_b= n_b ? b[n_b] : FIRST_DIGIT(b[0]);
+ gcalc_coord2 mul= cur_a * cur_b + carry + result[n_a + n_b + 1];
+ result[n_a + n_b + 1]= mul % GCALC_DIG_BASE;
carry= mul / GCALC_DIG_BASE;
} while (n_b--);
if (carry)
{
- for (n_res= n_a; (result->digits[n_res]+= carry) >= GCALC_DIG_BASE;
+ for (n_res= n_a; (result[n_res]+= carry) >= GCALC_DIG_BASE;
n_res--)
{
- result->digits[n_res]-= GCALC_DIG_BASE;
+ result[n_res]-= GCALC_DIG_BASE;
carry= 1;
}
carry= 0;
}
} while (n_a--);
- result->sign= a->sign != b->sign;
+ if (!gcalc_is_zero(result, result_len))
+ result[0]|= GCALC_SIGN(a[0] ^ b[0]);
#ifdef GCALC_CHECK_WITH_FLOAT
- GCALC_DBUG_ASSERT(de_check(a->get_double() * b->get_double(),
- result->get_double()));
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, a_len) *
+ gcalc_get_double(b, b_len),
+ gcalc_get_double(result, result_len)));
#endif /*GCALC_CHECK_WITH_FLOAT*/
}
-void gcalc_add_coord(Gcalc_internal_coord *result,
+inline void gcalc_mul_coord1(Gcalc_coord1 result,
+ const Gcalc_coord1 a, const Gcalc_coord1 b)
+{
+ return gcalc_mul_coord(result, GCALC_COORD_BASE2,
+ a, GCALC_COORD_BASE, b, GCALC_COORD_BASE);
+}
+
+
+void gcalc_add_coord(Gcalc_internal_coord *result, int result_len,
const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b)
{
- if (a->sign == b->sign)
- do_add(result, a, b);
+ if (GCALC_SIGN(a[0]) == GCALC_SIGN(b[0]))
+ do_add(result, result_len, a, b);
else
{
- int cmp_res= do_cmp(a, b);
+ int cmp_res= do_cmp(a, b, result_len);
if (cmp_res == 0)
- result->set_zero();
+ gcalc_set_zero(result, result_len);
else if (cmp_res > 0)
- do_sub(result, a, b);
+ do_sub(result, result_len, a, b);
else
- do_sub(result, b, a);
+ do_sub(result, result_len, b, a);
}
#ifdef GCALC_CHECK_WITH_FLOAT
- GCALC_DBUG_ASSERT(de_check(a->get_double() + b->get_double(),
- result->get_double()));
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, result_len) +
+ gcalc_get_double(b, result_len),
+ gcalc_get_double(result, result_len)));
#endif /*GCALC_CHECK_WITH_FLOAT*/
}
-void gcalc_sub_coord(Gcalc_internal_coord *result,
+void gcalc_sub_coord(Gcalc_internal_coord *result, int result_len,
const Gcalc_internal_coord *a,
const Gcalc_internal_coord *b)
{
- if (a->sign != b->sign)
- do_add(result, a, b);
+ if (GCALC_SIGN(a[0] ^ b[0]))
+ do_add(result, result_len, a, b);
else
{
- int cmp_res= do_cmp(a, b);
+ int cmp_res= do_cmp(a, b, result_len);
if (cmp_res == 0)
- result->set_zero();
+ gcalc_set_zero(result, result_len);
else if (cmp_res > 0)
- do_sub(result, a, b);
+ do_sub(result, result_len, a, b);
else
{
- do_sub(result, b, a);
- result->sign= 1 - result->sign;
+ do_sub(result, result_len, b, a);
+ result[0]^= GCALC_COORD_MINUS;
}
}
#ifdef GCALC_CHECK_WITH_FLOAT
- GCALC_DBUG_ASSERT(de_check(a->get_double() - b->get_double(),
- result->get_double()));
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, result_len) -
+ gcalc_get_double(b, result_len),
+ gcalc_get_double(result, result_len)));
#endif /*GCALC_CHECK_WITH_FLOAT*/
}
+inline void gcalc_sub_coord1(Gcalc_coord1 result,
+ const Gcalc_coord1 a, const Gcalc_coord1 b)
+{
+ return gcalc_sub_coord(result, GCALC_COORD_BASE, a, b);
+}
+
+
int gcalc_cmp_coord(const Gcalc_internal_coord *a,
- const Gcalc_internal_coord *b)
+ const Gcalc_internal_coord *b, int len)
{
- int result;
- if (a->sign != b->sign)
- return a->sign ? -1 : 1;
- result= a->sign ? do_cmp(b, a) : do_cmp(a, b);
+ int n_digit= 0;
+ int result= 0;
+
+ do
+ {
+ if (a[n_digit] == b[n_digit])
+ {
+ n_digit++;
+ continue;
+ }
+ if (a[n_digit] > b[n_digit])
+ result= GCALC_SIGN(a[0]) ? -1 : 1;
+ else
+ result= GCALC_SIGN(b[0]) ? 1 : -1;
+ break;
+
+ } while (n_digit < len);
+
#ifdef GCALC_CHECK_WITH_FLOAT
if (result == 0)
- GCALC_DBUG_ASSERT(de_check(a->get_double(), b->get_double()));
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, len),
+ gcalc_get_double(b, len)));
else if (result == 1)
- GCALC_DBUG_ASSERT(de_check(a->get_double(), b->get_double()) ||
- a->get_double() > b->get_double());
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, len),
+ gcalc_get_double(b, len)) ||
+ gcalc_get_double(a, len) > gcalc_get_double(b, len));
else
- GCALC_DBUG_ASSERT(de_check(a->get_double(), b->get_double()) ||
- a->get_double() < b->get_double());
+ GCALC_DBUG_ASSERT(de_check(gcalc_get_double(a, len),
+ gcalc_get_double(b, len)) ||
+ gcalc_get_double(a, len) < gcalc_get_double(b, len));
#endif /*GCALC_CHECK_WITH_FLOAT*/
return result;
}
-#define gcalc_cmp_coord1(a, b) gcalc_cmp_coord(a, b)
-
+#define gcalc_cmp_coord1(a, b) gcalc_cmp_coord(a, b, GCALC_COORD_BASE)
-int Gcalc_coord1::set_double(double d, double ext)
+int gcalc_set_double(Gcalc_internal_coord *c, double d, double ext)
{
+ int sign;
double ds= d * ext;
- init();
if ((sign= ds < 0))
ds= -ds;
c[0]= (gcalc_digit_t) (ds / (double) GCALC_DIG_BASE);
@@ -542,237 +609,70 @@ int Gcalc_coord1::set_double(double d, double ext)
c[1]= 0;
c[0]++;
}
+ if (sign)
+ c[0]|= GCALC_COORD_MINUS;
#ifdef GCALC_CHECK_WITH_FLOAT
- GCALC_DBUG_ASSERT(de_check(d, get_double()));
+ GCALC_DBUG_ASSERT(de_check(d, gcalc_get_double(c, 2)));
#endif /*GCALC_CHECK_WITH_FLOAT*/
return 0;
}
-void Gcalc_coord1::copy(const Gcalc_coord1 *from)
-{
- c[0]= from->c[0];
- c[1]= from->c[1];
- sign= from->sign;
-}
-
-
-#ifdef GCALC_CHECK_WITH_FLOAT
-static void calc_t(Gcalc_coord2 *t_a, Gcalc_coord2 *t_b,
- Gcalc_coord1 *b1x,
- Gcalc_coord1 *b1y,
- const Gcalc_heap::Info *p1,
- const Gcalc_heap::Info *p2,
- const Gcalc_heap::Info *p3,
- const Gcalc_heap::Info *p4)
-{
- Gcalc_coord1 a2_a1x, a2_a1y;
- Gcalc_coord1 b2x, b2y;
- Gcalc_coord2 x1y2, x2y1;
-
- a2_a1x.init();
- a2_a1y.init();
- x1y2.init();
- x2y1.init();
- t_a->init();
- t_b->init();
- b1y->init();
- b1x->init();
- b2x.init();
- b2y.init();
-
- gcalc_sub_coord(&a2_a1x, &p3->ix, &p1->ix);
- gcalc_sub_coord(&a2_a1y, &p3->iy, &p1->iy);
- gcalc_sub_coord(b1x, &p2->ix, &p1->ix);
- gcalc_sub_coord(b1y, &p2->iy, &p1->iy);
- gcalc_sub_coord(&b2x, &p4->ix, &p3->ix);
- gcalc_sub_coord(&b2y, &p4->iy, &p3->iy);
-
- GCALC_DBUG_ASSERT(!b1y->is_zero() || !b2y.is_zero());
-
- gcalc_mul_coord(&x1y2, b1x, &b2y);
- gcalc_mul_coord(&x2y1, &b2x, b1y);
- gcalc_sub_coord(t_b, &x1y2, &x2y1);
-
-
- gcalc_mul_coord(&x1y2, &a2_a1x, &b2y);
- gcalc_mul_coord(&x2y1, &a2_a1y, &b2x);
- gcalc_sub_coord(t_a, &x1y2, &x2y1);
-}
-
-
-static void calc_t(Gcalc_coord2 *t_a, Gcalc_coord2 *t_b,
- Gcalc_coord1 *b1x,
- Gcalc_coord1 *b1y,
- const Gcalc_heap::Info *i)
-{
- GCALC_DBUG_ASSERT(i->type == Gcalc_heap::nt_intersection);
- calc_t(t_a, t_b, b1x, b1y, i->p1, i->p2, i->p3, i->p4);
-}
-#endif /*GCALC_CHECK_WITH_FLOAT*/
-
-
-class Gcalc_coord4 : public Gcalc_internal_coord
-{
- gcalc_digit_t c[GCALC_COORD_BASE*4];
- public:
- void init()
- {
- n_digits= GCALC_COORD_BASE*4;
- digits= c;
- }
-};
-
-
-class Gcalc_coord5 : public Gcalc_internal_coord
-{
- gcalc_digit_t c[GCALC_COORD_BASE*5];
- public:
- void init()
- {
- n_digits= GCALC_COORD_BASE*5;
- digits= c;
- }
-};
-
-
-#ifdef TMP_BLOCK
-static void calc_isc_exp(Gcalc_coord5 *exp,
- const Gcalc_coord2 *bb2,
- const Gcalc_coord1 *ya1,
- const Gcalc_coord2 *bb1,
- const Gcalc_coord1 *yb1,
- const Gcalc_coord2 *a21_b1)
-{
- Gcalc_coord3 p1, p2, sum;
- p1.init();
- p2.init();
- sum.init();
- exp->init();
-
- gcalc_mul_coord(&p1, ya1, bb1);
- gcalc_mul_coord(&p2, yb1, a21_b1);
- gcalc_add_coord(&sum, &p1, &p2);
- gcalc_mul_coord(exp, bb2, &sum);
-}
-
-
-static int cmp_intersections(const Gcalc_heap::Info *i1,
- const Gcalc_heap::Info *i2)
-{
- Gcalc_coord2 t_a1, t_b1;
- Gcalc_coord2 t_a2, t_b2;
- Gcalc_coord1 yb1, yb2;
- Gcalc_coord1 xb1, xb2;
- Gcalc_coord5 exp_a, exp_b;
- int result;
-
- calc_t(&t_a1, &t_b1, &xb1, &yb1, i1);
- calc_t(&t_a2, &t_b2, &xb2, &yb2, i2);
-
- calc_isc_exp(&exp_a, &t_b2, &i1->p1->iy, &t_b1, &yb1, &t_a1);
- calc_isc_exp(&exp_b, &t_b1, &i2->p1->iy, &t_b2, &yb2, &t_a2);
-
- result= gcalc_cmp_coord(&exp_a, &exp_b);
-#ifdef GCALC_CHECK_WITH_FLOAT
- long double x1, y1, x2, y2;
- i1->calc_xy_ld(&x1, &y1);
- i2->calc_xy_ld(&x2, &y2);
-
- if (result == 0)
- GCALC_DBUG_ASSERT(de_check(y1, y2));
- if (result < 0)
- GCALC_DBUG_ASSERT(de_check(y1, y2) || y1 < y2);
- if (result > 0)
- GCALC_DBUG_ASSERT(de_check(y1, y2) || y1 > y2);
-#endif /*GCALC_CHECK_WITH_FLOAT*/
-
- if (result != 0)
- return result;
-
+typedef gcalc_digit_t Gcalc_coord4[GCALC_COORD_BASE*4];
+typedef gcalc_digit_t Gcalc_coord5[GCALC_COORD_BASE*5];
- calc_isc_exp(&exp_a, &t_b2, &i1->p1->ix, &t_b1, &xb1, &t_a1);
- calc_isc_exp(&exp_b, &t_b1, &i2->p1->ix, &t_b2, &xb2, &t_a2);
- result= gcalc_cmp_coord(&exp_a, &exp_b);
-#ifdef GCALC_CHECK_WITH_FLOAT
- if (result == 0)
- GCALC_DBUG_ASSERT(de_check(x1, x2));
- if (result < 0)
- GCALC_DBUG_ASSERT(de_check(x1, x2) || x1 < x2);
- if (result > 0)
- GCALC_DBUG_ASSERT(de_check(x1, x2) || x1 > x2);
-#endif /*GCALC_CHECK_WITH_FLOAT*/
- return result;
-}
-#endif /*TMP_BLOCK*/
-
-void Gcalc_scan_iterator::intersection_info::calc_t()
+void Gcalc_scan_iterator::intersection_info::do_calc_t()
{
- if (t_calculated)
- return;
-
Gcalc_coord1 a2_a1x, a2_a1y;
Gcalc_coord2 x1y2, x2y1;
- t_a.init();
- t_b.init();
- a2_a1x.init();
- a2_a1y.init();
- x1y2.init();
- x2y1.init();
+ gcalc_sub_coord1(a2_a1x, edge_b->pi->ix, edge_a->pi->ix);
+ gcalc_sub_coord1(a2_a1y, edge_b->pi->iy, edge_a->pi->iy);
- gcalc_sub_coord(&a2_a1x, &edge_b->pi->ix, &edge_a->pi->ix);
- gcalc_sub_coord(&a2_a1y, &edge_b->pi->iy, &edge_a->pi->iy);
+ GCALC_DBUG_ASSERT(!gcalc_is_zero(edge_a->dy, GCALC_COORD_BASE) ||
+ !gcalc_is_zero(edge_b->dy, GCALC_COORD_BASE));
- GCALC_DBUG_ASSERT(!edge_a->dy.is_zero() || !edge_b->dy.is_zero());
+ gcalc_mul_coord1(x1y2, edge_a->dx, edge_b->dy);
+ gcalc_mul_coord1(x2y1, edge_a->dy, edge_b->dx);
+ gcalc_sub_coord(t_b, GCALC_COORD_BASE2, x1y2, x2y1);
- gcalc_mul_coord(&x1y2, &edge_a->dx, &edge_b->dy);
- gcalc_mul_coord(&x2y1, &edge_a->dy, &edge_b->dx);
- gcalc_sub_coord(&t_b, &x1y2, &x2y1);
-
- gcalc_mul_coord(&x1y2, &a2_a1x, &edge_b->dy);
- gcalc_mul_coord(&x2y1, &a2_a1y, &edge_b->dx);
- gcalc_sub_coord(&t_a, &x1y2, &x2y1);
+ gcalc_mul_coord1(x1y2, a2_a1x, edge_b->dy);
+ gcalc_mul_coord1(x2y1, a2_a1y, edge_b->dx);
+ gcalc_sub_coord(t_a, GCALC_COORD_BASE2, x1y2, x2y1);
t_calculated= 1;
}
-void Gcalc_scan_iterator::intersection_info::calc_y_exp()
+void Gcalc_scan_iterator::intersection_info::do_calc_y()
{
- if (y_calculated)
- return;
GCALC_DBUG_ASSERT(t_calculated);
Gcalc_coord3 a_tb, b_ta;
- y_exp.init();
- a_tb.init();
- b_ta.init();
- gcalc_mul_coord(&a_tb, &t_b, &edge_a->pi->iy);
- gcalc_mul_coord(&b_ta, &t_a, &edge_a->dy);
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, edge_a->pi->iy, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, edge_a->dy, GCALC_COORD_BASE);
- gcalc_add_coord(&y_exp, &a_tb, &b_ta);
+ gcalc_add_coord(y_exp, GCALC_COORD_BASE3, a_tb, b_ta);
y_calculated= 1;
}
-void Gcalc_scan_iterator::intersection_info::calc_x_exp()
+void Gcalc_scan_iterator::intersection_info::do_calc_x()
{
- if (x_calculated)
- return;
GCALC_DBUG_ASSERT(t_calculated);
Gcalc_coord3 a_tb, b_ta;
- x_exp.init();
- a_tb.init();
- b_ta.init();
- gcalc_mul_coord(&a_tb, &t_b, &edge_a->pi->ix);
- gcalc_mul_coord(&b_ta, &t_a, &edge_a->dx);
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, edge_a->pi->ix, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, edge_a->dx, GCALC_COORD_BASE);
- gcalc_add_coord(&x_exp, &a_tb, &b_ta);
+ gcalc_add_coord(x_exp, GCALC_COORD_BASE3, a_tb, b_ta);
x_calculated= 1;
}
@@ -784,39 +684,61 @@ static int cmp_node_isc(const Gcalc_heap::Info *node,
Gcalc_scan_iterator::intersection_info *inf= i_data(isc);
Gcalc_coord3 exp;
int result;
- exp.init();
inf->calc_t();
inf->calc_y_exp();
- gcalc_mul_coord(&exp, &node->iy, &inf->t_b);
+ gcalc_mul_coord(exp, GCALC_COORD_BASE3,
+ inf->t_b, GCALC_COORD_BASE2, node->iy, GCALC_COORD_BASE);
- result= gcalc_cmp_coord(&exp, &inf->y_exp);
+ result= gcalc_cmp_coord(exp, inf->y_exp, GCALC_COORD_BASE3);
#ifdef GCALC_CHECK_WITH_FLOAT
long double int_x, int_y;
isc->calc_xy_ld(&int_x, &int_y);
if (result < 0)
- GCALC_DBUG_ASSERT(de_check(int_y, node->y) || node->y < int_y);
+ {
+ if (!de_check(int_y, node->y) && node->y > int_y)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g < %LG", node->y, int_y));
+ }
else if (result > 0)
- GCALC_DBUG_ASSERT(de_check(int_y, node->y) || node->y > int_y);
+ {
+ if (!de_check(int_y, node->y) && node->y < int_y)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g > %LG", node->y, int_y));
+ }
else
- GCALC_DBUG_ASSERT(de_check(int_y, node->y));
+ {
+ if (!de_check(int_y, node->y))
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscy %g == %LG", node->y, int_y));
+ }
#endif /*GCALC_CHECK_WITH_FLOAT*/
if (result)
goto exit;
inf->calc_x_exp();
- gcalc_mul_coord(&exp, &node->ix, &inf->t_b);
+ gcalc_mul_coord(exp, GCALC_COORD_BASE3,
+ inf->t_b, GCALC_COORD_BASE2, node->ix, GCALC_COORD_BASE);
- result= gcalc_cmp_coord(&exp, &inf->x_exp);
+ result= gcalc_cmp_coord(exp, inf->x_exp, GCALC_COORD_BASE3);
#ifdef GCALC_CHECK_WITH_FLOAT
if (result < 0)
- GCALC_DBUG_ASSERT(de_check(int_x, node->x) || node->x < int_x);
+ {
+ if (!de_check(int_x, node->x) && node->x > int_x)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g < %LG",
+ node->x, int_x));
+ }
else if (result > 0)
- GCALC_DBUG_ASSERT(de_check(int_x, node->x) || node->x > int_x);
+ {
+ if (!de_check(int_x, node->x) && node->x < int_x)
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g > %LG",
+ node->x, int_x));
+ }
else
- GCALC_DBUG_ASSERT(de_check(int_x, node->x));
+ {
+ if (!de_check(int_x, node->x))
+ GCALC_DBUG_PRINT(("floatcheck cmp_nod_iscx failed %g == %LG",
+ node->x, int_x));
+ }
#endif /*GCALC_CHECK_WITH_FLOAT*/
exit:
return result;
@@ -837,23 +759,35 @@ static int cmp_intersections(const Gcalc_heap::Info *i1,
inf1->calc_y_exp();
inf2->calc_y_exp();
- exp_a.init();
- exp_b.init();
- gcalc_mul_coord(&exp_a, &inf1->y_exp, &inf2->t_b);
- gcalc_mul_coord(&exp_b, &inf2->y_exp, &inf1->t_b);
+ gcalc_mul_coord(exp_a, GCALC_COORD_BASE5,
+ inf1->y_exp, GCALC_COORD_BASE3, inf2->t_b, GCALC_COORD_BASE2);
+ gcalc_mul_coord(exp_b, GCALC_COORD_BASE5,
+ inf2->y_exp, GCALC_COORD_BASE3, inf1->t_b, GCALC_COORD_BASE2);
- result= gcalc_cmp_coord(&exp_a, &exp_b);
+ result= gcalc_cmp_coord(exp_a, exp_b, GCALC_COORD_BASE5);
#ifdef GCALC_CHECK_WITH_FLOAT
long double x1, y1, x2, y2;
i1->calc_xy_ld(&x1, &y1);
i2->calc_xy_ld(&x2, &y2);
- if (result == 0)
- GCALC_DBUG_ASSERT(de_check(y1, y2));
if (result < 0)
- GCALC_DBUG_ASSERT(de_check(y1, y2) || y1 < y2);
- if (result > 0)
- GCALC_DBUG_ASSERT(de_check(y1, y2) || y1 > y2);
+ {
+ if (!de_check(y1, y2) && y2 > y1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersections_y failed %LG < %LG",
+ y2, y1));
+ }
+ else if (result > 0)
+ {
+ if (!de_check(y1, y2) && y2 < y1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersections_y failed %LG > %LG",
+ y2, y1));
+ }
+ else
+ {
+ if (!de_check(y1, y2))
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersections_y failed %LG == %LG",
+ y2, y1));
+ }
#endif /*GCALC_CHECK_WITH_FLOAT*/
if (result != 0)
@@ -862,17 +796,31 @@ static int cmp_intersections(const Gcalc_heap::Info *i1,
inf1->calc_x_exp();
inf2->calc_x_exp();
- gcalc_mul_coord(&exp_a, &inf1->x_exp, &inf2->t_b);
- gcalc_mul_coord(&exp_b, &inf2->x_exp, &inf1->t_b);
+ gcalc_mul_coord(exp_a, GCALC_COORD_BASE5,
+ inf1->x_exp, GCALC_COORD_BASE3, inf2->t_b, GCALC_COORD_BASE2);
+ gcalc_mul_coord(exp_b, GCALC_COORD_BASE5,
+ inf2->x_exp, GCALC_COORD_BASE3, inf1->t_b, GCALC_COORD_BASE2);
- result= gcalc_cmp_coord(&exp_a, &exp_b);
+ result= gcalc_cmp_coord(exp_a, exp_b, GCALC_COORD_BASE5);
#ifdef GCALC_CHECK_WITH_FLOAT
- if (result == 0)
- GCALC_DBUG_ASSERT(de_check(x1, x2));
if (result < 0)
- GCALC_DBUG_ASSERT(de_check(x1, x2) || x1 < x2);
- if (result > 0)
- GCALC_DBUG_ASSERT(de_check(x1, x2) || x1 > x2);
+ {
+ if (!de_check(x1, x2) && x2 > x1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersectionsx failed %LG < %LG",
+ x2, x1));
+ }
+ else if (result > 0)
+ {
+ if (!de_check(x1, x2) && x2 < x1)
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersectionsx failed %LG > %LG",
+ x2, x1));
+ }
+ else
+ {
+ if (!de_check(x1, x2))
+ GCALC_DBUG_PRINT(("floatcheck cmp_intersectionsx failed %LG == %LG",
+ x2, x1));
+ }
#endif /*GCALC_CHECK_WITH_FLOAT*/
return result;
}
@@ -959,43 +907,26 @@ void Gcalc_heap::Info::calc_xy(double *x, double *y) const
#ifdef GCALC_CHECK_WITH_FLOAT
void Gcalc_heap::Info::calc_xy_ld(long double *x, long double *y) const
{
- long double b0_x= p2->x - p1->x;
- long double b0_y= p2->y - p1->y;
- long double b1_x= p4->x - p3->x;
- long double b1_y= p4->y - p3->y;
+ long double b0_x= ((long double) p2->x) - p1->x;
+ long double b0_y= ((long double) p2->y) - p1->y;
+ long double b1_x= ((long double) p4->x) - p3->x;
+ long double b1_y= ((long double) p4->y) - p3->y;
long double b0xb1= b0_x * b1_y - b0_y * b1_x;
- long double t= (p3->x - p1->x) * b1_y - (p3->y - p1->y) * b1_x;
- long double cx, cy;
-
- t/= b0xb1;
+ long double ax= ((long double) p3->x) - p1->x;
+ long double ay= ((long double) p3->y) - p1->y;
+ long double t_a= ax * b1_y - ay * b1_x;
+ long double hx= (b0xb1 * (long double) p1->x + b0_x * t_a);
+ long double hy= (b0xb1 * (long double) p1->y + b0_y * t_a);
- cx= (long double) p1->x + b0_x * t;
- cy= (long double) p1->y + b0_y * t;
-
- Gcalc_coord2 t_a, t_b;
- Gcalc_coord1 yb, xb;
- Gcalc_coord3 m1, m2, sum;
-
- calc_t(&t_a, &t_b, &xb, &yb, this);
- if (t_b.is_zero())
+ if (fabs(b0xb1) < 1e-15)
{
*x= p1->x;
*y= p1->y;
return;
}
- m1.init();
- m2.init();
- sum.init();
- gcalc_mul_coord(&m1, &p1->ix, &t_b);
- gcalc_mul_coord(&m2, &xb, &t_a);
- gcalc_add_coord(&sum, &m1, &m2);
- *x= sum.get_double() / t_b.get_double();
-
- gcalc_mul_coord(&m1, &p1->iy, &t_b);
- gcalc_mul_coord(&m2, &yb, &t_a);
- gcalc_add_coord(&sum, &m1, &m2);
- *y= sum.get_double() / t_b.get_double();
+ *x= hx/b0xb1;
+ *y= hy/b0xb1;
}
#endif /*GCALC_CHECK_WITH_FLOAT*/
@@ -1003,10 +934,10 @@ void Gcalc_heap::Info::calc_xy_ld(long double *x, long double *y) const
static int cmp_point_info(const Gcalc_heap::Info *i0,
const Gcalc_heap::Info *i1)
{
- int cmp_y= gcalc_cmp_coord(&i0->iy, &i1->iy);
+ int cmp_y= gcalc_cmp_coord1(i0->iy, i1->iy);
if (cmp_y)
return cmp_y;
- return gcalc_cmp_coord(&i0->ix, &i1->ix);
+ return gcalc_cmp_coord1(i0->ix, i1->ix);
}
@@ -1048,14 +979,14 @@ void Gcalc_heap::prepare_operation()
GCALC_DBUG_ASSERT(m_hook);
coord_extent= find_scale(coord_extent);
#ifdef GCALC_CHECK_WITH_FLOAT
- Gcalc_internal_coord::coord_extent= &coord_extent;
+ gcalc_coord_extent= &coord_extent;
#endif /*GCALC_CHECK_WITH_FLOAT*/
*m_hook= NULL;
m_hook= NULL; /* just to check it's not called twice */
for (cur= get_first(); cur; cur= cur->get_next())
{
- cur->ix.set_double(cur->x, coord_extent);
- cur->iy.set_double(cur->y, coord_extent);
+ gcalc_set_double(cur->ix, cur->x, coord_extent);
+ gcalc_set_double(cur->iy, cur->y, coord_extent);
}
m_first= sort_list(compare_point_info, m_first, m_n_points);
@@ -1153,9 +1084,9 @@ void Gcalc_shape_transporter::int_complete()
inline void calc_dx_dy(Gcalc_scan_iterator::point *p)
{
- gcalc_sub_coord(&p->dx, &p->next_pi->ix, &p->pi->ix);
- gcalc_sub_coord(&p->dy, &p->next_pi->iy, &p->pi->iy);
- if (p->dx.sign)
+ gcalc_sub_coord1(p->dx, p->next_pi->ix, p->pi->ix);
+ gcalc_sub_coord1(p->dy, p->next_pi->iy, p->pi->iy);
+ if (GCALC_SIGN(p->dx[0]))
{
p->l_border= &p->next_pi->ix;
p->r_border= &p->pi->ix;
@@ -1203,19 +1134,17 @@ void Gcalc_scan_iterator::reset()
}
-int Gcalc_scan_iterator::point::cmp_dx_dy(const Gcalc_coord1 *dx_a,
- const Gcalc_coord1 *dy_a,
- const Gcalc_coord1 *dx_b,
- const Gcalc_coord1 *dy_b)
+int Gcalc_scan_iterator::point::cmp_dx_dy(const Gcalc_coord1 dx_a,
+ const Gcalc_coord1 dy_a,
+ const Gcalc_coord1 dx_b,
+ const Gcalc_coord1 dy_b)
{
Gcalc_coord2 dx_a_dy_b;
Gcalc_coord2 dy_a_dx_b;
- dx_a_dy_b.init();
- dy_a_dx_b.init();
- gcalc_mul_coord(&dx_a_dy_b, dx_a, dy_b);
- gcalc_mul_coord(&dy_a_dx_b, dy_a, dx_b);
+ gcalc_mul_coord1(dx_a_dy_b, dx_a, dy_b);
+ gcalc_mul_coord1(dy_a_dx_b, dy_a, dx_b);
- return gcalc_cmp_coord(&dx_a_dy_b, &dy_a_dx_b);
+ return gcalc_cmp_coord(dx_a_dy_b, dy_a_dx_b, GCALC_COORD_BASE2);
}
@@ -1225,22 +1154,18 @@ int Gcalc_scan_iterator::point::cmp_dx_dy(const Gcalc_heap::Info *p1,
const Gcalc_heap::Info *p4)
{
Gcalc_coord1 dx_a, dy_a, dx_b, dy_b;
- dx_a.init();
- dx_b.init();
- dy_a.init();
- dy_b.init();
- gcalc_sub_coord(&dx_a, &p2->ix, &p1->ix);
- gcalc_sub_coord(&dy_a, &p2->iy, &p1->iy);
- gcalc_sub_coord(&dx_b, &p4->ix, &p3->ix);
- gcalc_sub_coord(&dy_b, &p4->iy, &p3->iy);
- return cmp_dx_dy(&dx_a, &dy_a, &dx_b, &dy_b);
+ gcalc_sub_coord1(dx_a, p2->ix, p1->ix);
+ gcalc_sub_coord1(dy_a, p2->iy, p1->iy);
+ gcalc_sub_coord1(dx_b, p4->ix, p3->ix);
+ gcalc_sub_coord1(dy_b, p4->iy, p3->iy);
+ return cmp_dx_dy(dx_a, dy_a, dx_b, dy_b);
}
int Gcalc_scan_iterator::point::cmp_dx_dy(const point *p) const
{
GCALC_DBUG_ASSERT(!is_bottom());
- return cmp_dx_dy(&dx, &dy, &p->dx, &p->dy);
+ return cmp_dx_dy(dx, dy, p->dx, p->dy);
}
@@ -1248,13 +1173,14 @@ int Gcalc_scan_iterator::point::cmp_dx_dy(const point *p) const
void Gcalc_scan_iterator::point::calc_x(long double *x, long double y,
long double ix) const
{
- long double ddy= dy.get_double();
+ long double ddy= gcalc_get_double(dy, GCALC_COORD_BASE);
if (fabsl(ddy) < (long double) 1e-20)
{
*x= ix;
}
else
- *x= (ddy * (long double) pi->x + dx.get_double() * (y - pi->y)) / ddy;
+ *x= (ddy * (long double) pi->x + gcalc_get_double(dx, GCALC_COORD_BASE) *
+ (y - pi->y)) / ddy;
}
#endif /*GCALC_CHECK_WITH_FLOAT*/
@@ -1457,20 +1383,35 @@ static int node_on_right(const Gcalc_heap::Info *node,
Gcalc_coord1 a_x, a_y;
Gcalc_coord1 b_x, b_y;
Gcalc_coord2 ax_by, ay_bx;
- a_x.init();
- a_y.init();
- b_x.init();
- b_y.init();
- ax_by.init();
- ay_bx.init();
+ int result;
- gcalc_sub_coord(&a_x, &node->ix, &edge_a->ix);
- gcalc_sub_coord(&a_y, &node->iy, &edge_a->iy);
- gcalc_sub_coord(&b_x, &edge_b->ix, &edge_a->ix);
- gcalc_sub_coord(&b_y, &edge_b->iy, &edge_a->iy);
- gcalc_mul_coord(&ax_by, &a_x, &b_y);
- gcalc_mul_coord(&ay_bx, &a_y, &b_x);
- return gcalc_cmp_coord(&ax_by, &ay_bx);
+ gcalc_sub_coord1(a_x, node->ix, edge_a->ix);
+ gcalc_sub_coord1(a_y, node->iy, edge_a->iy);
+ gcalc_sub_coord1(b_x, edge_b->ix, edge_a->ix);
+ gcalc_sub_coord1(b_y, edge_b->iy, edge_a->iy);
+ gcalc_mul_coord1(ax_by, a_x, b_y);
+ gcalc_mul_coord1(ay_bx, a_y, b_x);
+ result= gcalc_cmp_coord(ax_by, ay_bx, GCALC_COORD_BASE2);
+#ifdef GCALC_CHECK_WITH_FLOAT
+ {
+ long double dx= gcalc_get_double(edge_b->ix, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->ix, GCALC_COORD_BASE);
+ long double dy= gcalc_get_double(edge_b->iy, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->iy, GCALC_COORD_BASE);
+ long double ax= gcalc_get_double(node->ix, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->ix, GCALC_COORD_BASE);
+ long double ay= gcalc_get_double(node->iy, GCALC_COORD_BASE) -
+ gcalc_get_double(edge_a->iy, GCALC_COORD_BASE);
+ long double d= ax * dy - ay * dx;
+ if (result == 0)
+ GCALC_DBUG_ASSERT(de_check(d, 0.0));
+ else if (result < 0)
+ GCALC_DBUG_ASSERT(de_check(d, 0.0) || d < 0);
+ else
+ GCALC_DBUG_ASSERT(de_check(d, 0.0) || d > 0);
+ }
+#endif /*GCALC_CHECK_WITH_FLOAT*/
+ return result;
}
@@ -1479,8 +1420,8 @@ static int cmp_tops(const Gcalc_heap::Info *top_node,
{
int cmp_res_a, cmp_res_b;
- cmp_res_a= gcalc_cmp_coord1(&edge_a->ix, &top_node->ix);
- cmp_res_b= gcalc_cmp_coord1(&edge_b->ix, &top_node->ix);
+ cmp_res_a= gcalc_cmp_coord1(edge_a->ix, top_node->ix);
+ cmp_res_b= gcalc_cmp_coord1(edge_b->ix, top_node->ix);
if (cmp_res_a <= 0 && cmp_res_b > 0)
return -1;
@@ -1534,7 +1475,7 @@ int Gcalc_scan_iterator::insert_top_node()
else if (cmp_res == 0)
{
/* Exactly same direction of the edges. */
- cmp_res= gcalc_cmp_coord1(&m_cur_pi->left->iy, &m_cur_pi->right->iy);
+ cmp_res= gcalc_cmp_coord1(m_cur_pi->left->iy, m_cur_pi->right->iy);
if (cmp_res != 0)
{
if (cmp_res < 0)
@@ -1550,7 +1491,7 @@ int Gcalc_scan_iterator::insert_top_node()
}
else
{
- cmp_res= gcalc_cmp_coord1(&m_cur_pi->left->ix, &m_cur_pi->right->ix);
+ cmp_res= gcalc_cmp_coord1(m_cur_pi->left->ix, m_cur_pi->right->ix);
if (cmp_res != 0)
{
if (cmp_res < 0)
@@ -1584,7 +1525,7 @@ int Gcalc_scan_iterator::insert_top_node()
/* We need to find the place to insert. */
for (; sp; prev_hook= sp->next_ptr(), sp=sp->get_next())
{
- if (sp->event || gcalc_cmp_coord(sp->r_border, &m_cur_pi->ix) < 0)
+ if (sp->event || gcalc_cmp_coord1(*sp->r_border, m_cur_pi->ix) < 0)
continue;
cmp_res= node_on_right(m_cur_pi, sp->pi, sp->next_pi);
if (cmp_res == 0)
@@ -1683,7 +1624,7 @@ int Gcalc_scan_iterator::add_events_for_node(point *sp_node)
GCALC_DBUG_ASSERT(!sp->is_bottom());
GCALC_DBUG_PRINT(("left cut_edge %d", sp->thread));
if (sp->next_pi == sp_node->next_pi ||
- gcalc_cmp_coord1(sp->r_border, sp_node->l_border) < 0)
+ gcalc_cmp_coord1(*sp->r_border, *sp_node->l_border) < 0)
continue;
sp_pi_r= node_on_right(sp->next_pi, sp_node->pi, sp_node->next_pi);
if (sp_pi_r < 0)
@@ -1743,7 +1684,7 @@ int Gcalc_scan_iterator::add_events_for_node(point *sp_node)
GCALC_DBUG_ASSERT(!sp->is_bottom());
GCALC_DBUG_PRINT(("right cut_edge %d", sp->thread));
if (sp->next_pi == sp_node->next_pi ||
- gcalc_cmp_coord1(sp_node->r_border, sp->l_border) < 0)
+ gcalc_cmp_coord1(*sp_node->r_border, *sp->l_border) < 0)
continue;
sp_pi_r= node_on_right(sp->next_pi, sp_node->pi, sp_node->next_pi);
if (sp_pi_r > 0)
@@ -1942,13 +1883,54 @@ int Gcalc_scan_iterator::add_eq_node(Gcalc_heap::Info *node, point *sp)
}
+void calc_t(Gcalc_coord2 t_a, Gcalc_coord2 t_b,
+ Gcalc_coord1 dxa, Gcalc_coord1 dxb,
+ const Gcalc_heap::Info *p1, const Gcalc_heap::Info *p2,
+ const Gcalc_heap::Info *p3, const Gcalc_heap::Info *p4)
+{
+ Gcalc_coord1 a2_a1x, a2_a1y;
+ Gcalc_coord2 x1y2, x2y1;
+ Gcalc_coord1 dya, dyb;
+
+ gcalc_sub_coord1(a2_a1x, p3->ix, p1->ix);
+ gcalc_sub_coord1(a2_a1y, p3->iy, p1->iy);
+
+ gcalc_sub_coord1(dxa, p2->ix, p1->ix);
+ gcalc_sub_coord1(dya, p2->iy, p1->iy);
+ gcalc_sub_coord1(dxb, p4->ix, p3->ix);
+ gcalc_sub_coord1(dyb, p4->iy, p3->iy);
+
+ gcalc_mul_coord1(x1y2, dxa, dyb);
+ gcalc_mul_coord1(x2y1, dya, dxb);
+ gcalc_sub_coord(t_b, GCALC_COORD_BASE2, x1y2, x2y1);
+
+
+ gcalc_mul_coord1(x1y2, a2_a1x, dyb);
+ gcalc_mul_coord1(x2y1, a2_a1y, dxb);
+ gcalc_sub_coord(t_a, GCALC_COORD_BASE2, x1y2, x2y1);
+}
+
+
double Gcalc_scan_iterator::get_y() const
{
if (state.pi->type == Gcalc_heap::nt_intersection)
{
- double x, y;
- state.pi->calc_xy(&x, &y);
- return y;
+ Gcalc_coord1 dxa, dya;
+ Gcalc_coord2 t_a, t_b;
+ Gcalc_coord3 a_tb, b_ta, y_exp;
+ calc_t(t_a, t_b, dxa, dya,
+ state.pi->p1, state.pi->p2, state.pi->p3, state.pi->p4);
+
+
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, state.pi->p1->iy, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, dya, GCALC_COORD_BASE);
+
+ gcalc_add_coord(y_exp, GCALC_COORD_BASE3, a_tb, b_ta);
+
+ return (get_pure_double(y_exp, GCALC_COORD_BASE3) /
+ get_pure_double(t_b, GCALC_COORD_BASE2)) / m_heap->coord_extent;
}
else
return state.pi->y;
@@ -1959,9 +1941,22 @@ double Gcalc_scan_iterator::get_event_x() const
{
if (state.pi->type == Gcalc_heap::nt_intersection)
{
- double x, y;
- state.pi->calc_xy(&x, &y);
- return x;
+ Gcalc_coord1 dxa, dya;
+ Gcalc_coord2 t_a, t_b;
+ Gcalc_coord3 a_tb, b_ta, x_exp;
+ calc_t(t_a, t_b, dxa, dya,
+ state.pi->p1, state.pi->p2, state.pi->p3, state.pi->p4);
+
+
+ gcalc_mul_coord(a_tb, GCALC_COORD_BASE3,
+ t_b, GCALC_COORD_BASE2, state.pi->p1->ix, GCALC_COORD_BASE);
+ gcalc_mul_coord(b_ta, GCALC_COORD_BASE3,
+ t_a, GCALC_COORD_BASE2, dxa, GCALC_COORD_BASE);
+
+ gcalc_add_coord(x_exp, GCALC_COORD_BASE3, a_tb, b_ta);
+
+ return (get_pure_double(x_exp, GCALC_COORD_BASE3) /
+ get_pure_double(t_b, GCALC_COORD_BASE2)) / m_heap->coord_extent;
}
else
return state.pi->x;
@@ -1994,4 +1989,21 @@ double Gcalc_scan_iterator::get_sp_x(const point *sp) const
}
+double Gcalc_scan_iterator::get_pure_double(const Gcalc_internal_coord *d,
+ int d_len)
+{
+ int n= 1;
+ long double res= (long double) FIRST_DIGIT(d[0]);
+ do
+ {
+ res*= (long double) GCALC_DIG_BASE;
+ res+= (long double) d[n];
+ } while(++n < d_len);
+
+ if (GCALC_SIGN(d[0]))
+ res*= -1.0;
+ return res;
+}
+
+
#endif /* HAVE_SPATIAL */