several bugs fixed here.
849789 Second assertion `m_poly_borders->next' failed in Gcalc_operation_reducer::count_slice in maria-5.3-gis 849791 Fourth assertion `n > 0 && n < SINUSES_CALCULATED*2+1' in get_n_sincos 849789 Second assertion `m_poly_borders->next' failed in Gcalc_operation_reducer::count_slice in maria-5.3-gis 848901 Assertion `fabs(cur_isc->x-m_cur_intersection->x) + fabs(cur_isc->y-m_cur_intersection->y) < 0.000000000001' failed in Gcalc_scan_iterator::intersection_scan() in maria-5.3-gis per-file comments: mysql-test/r/gis-precise.result test result updated. mysql-test/r/gis.result test result updated. sql/gcalc_slicescan.cc bugfixes. sql/gcalc_slicescan.h bugfixes. sql/gcalc_tools.cc bugfixes. sql/gcalc_tools.h bugfixes. sql/item_geofunc.cc bugfixes. sql/spatial.cc bugfixes.
This commit is contained in:
parent
5a04ac7bf0
commit
0249413a6a
@ -189,7 +189,7 @@ st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('point(1
|
||||
0
|
||||
select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))'));
|
||||
st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1.2, 1 0, 2 0, 1 1.2))'))
|
||||
1
|
||||
0
|
||||
select st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))'));
|
||||
st_touches(geomfromtext('polygon((0 0, 2 2, 0 4, 0 0))'), geomfromtext('polygon((1 1, 1 0, 2 0, 1 1))'))
|
||||
1
|
||||
@ -257,7 +257,7 @@ ST_NUMGEOMETRIES((ST_UNION(ST_UNION(
|
||||
MULTILINESTRINGFROMTEXT('MULTILINESTRING((2 0,4 2,0 2,1 5,0 3,7 0,8 5,5 8),
|
||||
(6 2,4 0,3 5,3 6,4 3,6 4,3 9,0 7,3 7,8 4,2 9,5 0),
|
||||
|
||||
176
|
||||
185
|
||||
SELECT Round(ST_AREA(ST_BUFFER( ST_UNION(
|
||||
POLYGONFROMTEXT('POLYGON((7 7, 7 7, 7 4, 7 7, 7 7))'),
|
||||
POLYGONFROMTEXT('POLYGON((7 7, 4 7, 2 9, 7 6, 7 7))')), 1)), 6);
|
||||
@ -338,7 +338,7 @@ MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2, 1 5))')
|
||||
ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER(ST_UNION(
|
||||
MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 2 5, 7 6, 1 8),(0 0 ,1 6 ,0 1, 8 9, 2 4, 6 1, 3 5, 4 8), (9 3, 5 4, 1 8, 4 2, 5 8, 3 0))' ) ,
|
||||
MULTILINESTRINGFROMTEXT('MULTILINESTRING((3 4, 3 1, 2 7, 4 2, 6 2
|
||||
280
|
||||
275
|
||||
SELECT ST_NUMGEOMETRIES(ST_DIFFERENCE (
|
||||
ST_UNION (
|
||||
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 ) ) ' ),
|
||||
@ -354,7 +354,7 @@ MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 9 , 1 3 , 7 3 , 8 5 ) , ( 5 0 ,
|
||||
ST_NUMGEOMETRIES(ST_DIFFERENCE (
|
||||
ST_UNION (
|
||||
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 4 , 5 0 , 2 9 , 6 2 , 0 2 ) , ( 4 3 , 5 6 , 9 4 , 0 7 , 7 2 , 2 0 , 8 2 ) , ( 5 0 , 1 5 , 3 7 , 7 7 ) , ( 2 3 , 9 5 , 2 0 , 8 1 ) , ( 0 9 , 9 3 , 2 8 , 8 1 , 9 4 )
|
||||
126
|
||||
123
|
||||
SELECT ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER (
|
||||
ST_UNION (
|
||||
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 7 3 , 1 8 , 4 0 , 7 9 ) , ( 5 4 , 9 8 , 7 4 , 3 7 ) , ( 5 8 , 5 4 , 9 2 , 5 6 ) , ( 4 0 , 3 2 , 0 1 , 3 9 ) , ( 2 0 , 3 5 , 9 5 , 0 9 ) ) ' ) ,
|
||||
@ -365,7 +365,7 @@ ST_NUMPOINTS(ST_EXTERIORRING(ST_BUFFER (
|
||||
ST_UNION (
|
||||
MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 7 3 , 1 8 , 4 0 , 7 9 ) , ( 5 4 , 9 8 , 7 4 , 3 7 ) , ( 5 8 , 5 4 , 9 2 , 5 6 ) , ( 4 0 , 3 2 , 0 1 , 3 9 ) , ( 2 0 , 3 5 , 9 5 , 0 9 ) ) ' ) ,
|
||||
MULTILINESTRI
|
||||
659
|
||||
653
|
||||
SELECT ASTEXT(ST_DIFFERENCE (
|
||||
POLYGONFROMTEXT( ' POLYGON( ( 2 2 , 2 8 , 8 8 , 8 2 , 2 2 ) , ( 4 4 , 4 6 , 6 6 , 6 4 , 4 4 ) ) ' ) ,
|
||||
ST_UNION (
|
||||
@ -416,7 +416,7 @@ ST_DISTANCE ( ST_DIFFERENCE ( MULTIPOLYGONFR
|
||||
NULL
|
||||
SELECT ST_NUMGEOMETRIES( ST_SYMDIFFERENCE ( ST_SYMDIFFERENCE ( ST_INTERSECTION ( MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 6 4 , 3 7 , 9 4 , 3 8 ) , ( 2 2 , 2 9 , 1 2 , 9 8 ) ) ' ) , ST_SYMDIFFERENCE ( MULTIPOINTFROMTEXT( ' MULTIPOINT( 6 1 , 3 8 , 3 3 , 0 6 , 7 2 , 3 4 ) ' ) , ST_BUFFER ( ST_UNION ( MULTIPOLYGONFROMTEXT( ' MULTIPOLYGON( ( ( 2 2 , 6 2 , 1 3 , 2 2 , 2 2 ) ) ) ' ) , GEOMETRYFROMTEXT( ' MULTILINESTRING( ( 1 4 , 9 9 , 3 0 , 6 6 ) , ( 3 5 , 1 0 , 5 8 , 6 1 ) , ( 8 9 , 6 1 , 5 1 , 6 2 ) , ( 2 2 , 7 5 , 5 8 , 6 9 , 3 0 ) , ( 8 0 , 8 4 , 6 7 , 5 5 ) ) ' ) ) , NUMPOINTS( EXTERIORRING( POLYGONFROMTEXT( ' POLYGON( ( 0 0 , 2 1 , 8 2 , 0 0 ) ) ' ) ) ) ) ) ) , ST_INTERSECTION ( POLYGONFROMTEXT( ' POLYGON( ( 2 3, 5 7 , 3 7 , 4 1 , 0 5, 2 3 ) ) ' ) , MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 2 3 , 1 4 , 6 4 , 9 1 , 3 4 , 1 8 ) , ( 9 9 , 0 3 , 1 7 , 9 9 ) ) ' ) ) ) , POLYGONFROMTEXT( ' POLYGON( ( 1 3, 7 2 , 1 5 , 3 8 , 5 0, 1 3) ) ' ) ) ) ;
|
||||
ST_NUMGEOMETRIES( ST_SYMDIFFERENCE ( ST_SYMDIFFERENCE ( ST_INTERSECTION ( MULTILINESTRINGFROMTEXT( ' MULTILINESTRING( ( 6 4 , 3 7 , 9 4 , 3 8 ) , ( 2 2 , 2 9 , 1 2 , 9 8 ) ) ' ) , ST_SYMDIFFERENCE ( MULTIPOINTFROMTEXT( ' MULTIPOINT( 6 1 , 3 8 , 3 3 , 0 6
|
||||
27
|
||||
25
|
||||
SELECT ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5)))'), geomETRYFROMTEXT(' MULTILINESTRING( ( 5 1 , 3 7 , 6 1 , 7 0 ) , ( 1 6 , 8 5 , 7 5 , 5 6 ) )') ));
|
||||
ASTEXT(ST_INTERSECTION( GEOMETRYFROMTEXT('GEOMETRYCOLLECTION(LINESTRING(7 7,5.33333333333333 7),LINESTRING(5.33333333333333 7,0 7,5 8,5.33333333333333 7),LINESTRING(5.33333333333333 7,7 2,7 7),POLYGON((0 5,3 5,3 2,1 2,1 1,3 1,3 0,0 0,0 3,2 3,2 4,0 4,0 5))
|
||||
MULTIPOINT(7 5,7 5.14285714285714,5.9 5.3,5.8 5.6,3 7)
|
||||
|
@ -850,7 +850,7 @@ mbroverlaps
|
||||
down,left,right,up
|
||||
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
|
||||
mbrtouches
|
||||
big,center,down,down2,left,left2,right,right2,small,up,up2
|
||||
down2,left2,right2,up2
|
||||
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
|
||||
mbrwithin
|
||||
big,center
|
||||
@ -871,7 +871,7 @@ overlaps
|
||||
down,left,right,up
|
||||
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
|
||||
touches
|
||||
big,center,down,down2,left,left2,right,right2,small,up,up2
|
||||
down2,left2,right2,up2
|
||||
SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name;
|
||||
within
|
||||
big,center
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -59,8 +59,11 @@ public:
|
||||
}
|
||||
inline void free_list(Item *list, Item **hook)
|
||||
{
|
||||
*hook= m_free;
|
||||
m_free= list;
|
||||
if (*hook != list)
|
||||
{
|
||||
*hook= m_free;
|
||||
m_free= list;
|
||||
}
|
||||
}
|
||||
|
||||
void free_list(Item *list)
|
||||
@ -91,6 +94,79 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
/* Internal Gcalc coordinates to provide the precise calculations */
|
||||
|
||||
#define DIG_BASE 1000000000
|
||||
typedef int32 coord_digit_t;
|
||||
typedef long long coord2;
|
||||
|
||||
#define C_SCALE 1e13
|
||||
#define COORD_BASE 2
|
||||
#ifndef DBUG_OFF
|
||||
//#define GCALC_CHECK_WITH_FLOAT
|
||||
#define NO_TESTING
|
||||
#else
|
||||
#define NO_TESTING
|
||||
#endif /*DBUG_OFF*/
|
||||
|
||||
class Gcalc_internal_coord
|
||||
{
|
||||
public:
|
||||
coord_digit_t *digits;
|
||||
int sign;
|
||||
int n_digits;
|
||||
void set_zero();
|
||||
int is_zero() const;
|
||||
#ifdef GCALC_CHECK_WITH_FLOAT
|
||||
long double get_double() const;
|
||||
#endif /*GCALC_CHECK_WITH_FLOAT*/
|
||||
};
|
||||
|
||||
|
||||
class Gcalc_coord1 : public Gcalc_internal_coord
|
||||
{
|
||||
coord_digit_t c[COORD_BASE];
|
||||
public:
|
||||
void init()
|
||||
{
|
||||
n_digits= COORD_BASE;
|
||||
digits= c;
|
||||
}
|
||||
int set_double(double d);
|
||||
void copy(const Gcalc_coord1 *from);
|
||||
};
|
||||
|
||||
|
||||
class Gcalc_coord2 : public Gcalc_internal_coord
|
||||
{
|
||||
coord_digit_t c[COORD_BASE*2];
|
||||
public:
|
||||
void init()
|
||||
{
|
||||
n_digits= COORD_BASE*2;
|
||||
digits= c;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void gcalc_mul_coord(Gcalc_internal_coord *result,
|
||||
const Gcalc_internal_coord *a,
|
||||
const Gcalc_internal_coord *b);
|
||||
|
||||
void gcalc_add_coord(Gcalc_internal_coord *result,
|
||||
const Gcalc_internal_coord *a,
|
||||
const Gcalc_internal_coord *b);
|
||||
|
||||
void gcalc_sub_coord(Gcalc_internal_coord *result,
|
||||
const Gcalc_internal_coord *a,
|
||||
const Gcalc_internal_coord *b);
|
||||
|
||||
int gcalc_cmp_coord(const Gcalc_internal_coord *a,
|
||||
const Gcalc_internal_coord *b);
|
||||
|
||||
/* Internal coordinates declarations end. */
|
||||
|
||||
|
||||
typedef uint gcalc_shape_info;
|
||||
|
||||
/*
|
||||
@ -114,27 +190,34 @@ public:
|
||||
Info *left;
|
||||
Info *right;
|
||||
double x,y;
|
||||
Gcalc_coord1 ix, iy;
|
||||
|
||||
inline bool is_bottom() const { return !left; }
|
||||
inline Info *get_next() { return (Info *)next; }
|
||||
inline const Info *get_next() const { return (const Info *)next; }
|
||||
};
|
||||
class Intersection_info : public Gcalc_dyn_list::Item
|
||||
{
|
||||
public:
|
||||
/* Line p1-p2 supposed to intersect line p3-p4 */
|
||||
const Info *p1;
|
||||
const Info *p2;
|
||||
const Info *p3;
|
||||
const Info *p4;
|
||||
void calc_xy(double *x, double *y) const;
|
||||
#ifdef GCALC_CHECK_WITH_FLOAT
|
||||
void calc_xy_ld(long double *x, long double *y) const;
|
||||
#endif /*GCALC_CHECK_WITH_FLOAT*/
|
||||
};
|
||||
|
||||
Gcalc_heap(size_t blk_size=8192) :
|
||||
Gcalc_dyn_list(blk_size, sizeof(Info)), m_hook(&m_first), m_n_points(0) {}
|
||||
Info *new_point_info(double x, double y, gcalc_shape_info shape)
|
||||
{
|
||||
Info *result= (Info *)new_item();
|
||||
if (!result)
|
||||
return NULL;
|
||||
*m_hook= result;
|
||||
m_hook= &result->next;
|
||||
m_n_points++;
|
||||
result->x= x;
|
||||
result->y= y;
|
||||
result->shape= shape;
|
||||
return result;
|
||||
}
|
||||
Gcalc_dyn_list(blk_size, sizeof(Info)),
|
||||
m_hook(&m_first), m_n_points(0),
|
||||
m_intersection_hook((Gcalc_dyn_list::Item **) &m_first_intersection)
|
||||
{}
|
||||
Info *new_point_info(double x, double y, gcalc_shape_info shape);
|
||||
Intersection_info *new_intersection(const Info *p1, const Info *p2,
|
||||
const Info *p3, const Info *p4);
|
||||
void prepare_operation();
|
||||
inline bool ready() const { return m_hook == NULL; }
|
||||
Info *get_first() { return (Info *)m_first; }
|
||||
@ -145,6 +228,8 @@ private:
|
||||
Gcalc_dyn_list::Item *m_first;
|
||||
Gcalc_dyn_list::Item **m_hook;
|
||||
int m_n_points;
|
||||
Intersection_info *m_first_intersection;
|
||||
Gcalc_dyn_list::Item **m_intersection_hook;
|
||||
};
|
||||
|
||||
|
||||
@ -263,9 +348,13 @@ public:
|
||||
class point : public Gcalc_dyn_list::Item
|
||||
{
|
||||
public:
|
||||
#ifdef TMP_BLOCK
|
||||
double x;
|
||||
double dx_dy;
|
||||
int horiz_dir;
|
||||
#endif /*TMP_BLOCK*/
|
||||
Gcalc_coord1 dx;
|
||||
Gcalc_coord1 dy;
|
||||
Gcalc_heap::Info *pi;
|
||||
Gcalc_heap::Info *next_pi;
|
||||
sc_thread_id thread;
|
||||
@ -273,22 +362,32 @@ public:
|
||||
const point *intersection_link;
|
||||
Gcalc_scan_events event;
|
||||
#ifdef TO_REMOVE
|
||||
const point *event_pair;
|
||||
point *next_link;
|
||||
#endif /*TO_REMOVE*/
|
||||
|
||||
inline const point *c_get_next() const
|
||||
{ return (const point *)next; }
|
||||
inline bool is_bottom() const { return pi->is_bottom(); }
|
||||
inline bool is_bottom() const { return !next_pi; }
|
||||
gcalc_shape_info get_shape() const { return pi->shape; }
|
||||
inline point *get_next() { return (point *)next; }
|
||||
inline const point *get_next() const { return (const point *)next; }
|
||||
/* copies all but 'next' 'x' and 'precursor' */
|
||||
void copy_core(point *from);
|
||||
void copy_core(const point *from);
|
||||
void copy_all(const point *from);
|
||||
/* Compare the dx_dy parameters regarding the horiz_dir */
|
||||
/* returns -1 if less, 0 if equal, 1 if bigger */
|
||||
static int compare_dx_dy(int horiz_dir_a, double dx_dy_a,
|
||||
int horiz_dir_b, double dx_dy_b);
|
||||
#ifdef TMP_BLOCK
|
||||
static int cmp_dx_dy(int horiz_dir_a, double dx_dy_a,
|
||||
int horiz_dir_b, double dx_dy_b);
|
||||
#endif /*TMP_BLOCK*/
|
||||
static int cmp_dx_dy(const Gcalc_coord1 *dx_a,
|
||||
const Gcalc_coord1 *dy_a,
|
||||
const Gcalc_coord1 *dx_b,
|
||||
const Gcalc_coord1 *dy_b);
|
||||
static int cmp_dx_dy(const Gcalc_heap::Info *p1,
|
||||
const Gcalc_heap::Info *p2,
|
||||
const Gcalc_heap::Info *p3,
|
||||
const Gcalc_heap::Info *p4);
|
||||
int cmp_dx_dy(const point *p) const;
|
||||
int simple_event() const
|
||||
{
|
||||
@ -298,6 +397,9 @@ public:
|
||||
#ifndef DBUG_OFF
|
||||
void dbug_print();
|
||||
#endif /*DBUG_OFF*/
|
||||
#ifdef GCALC_CHECK_WITH_FLOAT
|
||||
void calc_x(long double *x, long double y, long double ix) const;
|
||||
#endif /*GCALC_CHECK_WITH_FLOAT*/
|
||||
};
|
||||
|
||||
class intersection : public Gcalc_dyn_list::Item
|
||||
@ -306,8 +408,11 @@ public:
|
||||
int n_row;
|
||||
sc_thread_id thread_a;
|
||||
sc_thread_id thread_b;
|
||||
#ifdef TMP_BLOCK
|
||||
double x;
|
||||
double y;
|
||||
#endif /*TMP_BLOCK*/
|
||||
const Gcalc_heap::Intersection_info *ii;
|
||||
inline intersection *get_next() { return (intersection *)next; }
|
||||
};
|
||||
|
||||
@ -318,7 +423,15 @@ public:
|
||||
point *event_position;
|
||||
Gcalc_dyn_list::Item **event_position_hook;
|
||||
Gcalc_dyn_list::Item **event_end_hook;
|
||||
int intersection_scan;
|
||||
union
|
||||
{
|
||||
const Gcalc_heap::Info *pi;
|
||||
const Gcalc_heap::Intersection_info *isc;
|
||||
};
|
||||
#ifdef TMP_BLOCK
|
||||
double y;
|
||||
#endif /*TMP_BLOCK*/
|
||||
slice_state() : slice(NULL) {}
|
||||
void clear_event_position()
|
||||
{
|
||||
@ -350,10 +463,24 @@ public:
|
||||
{ return (point *) *current_state->event_end_hook; }
|
||||
inline const point *get_b_slice() const { return current_state->slice; }
|
||||
inline const point *get_t_slice() const { return next_state->slice; }
|
||||
inline double get_h() const { return current_state->y - next_state->y; }
|
||||
inline double get_y() const { return current_state->y; }
|
||||
double get_h() const;
|
||||
double get_y() const;
|
||||
double get_event_x() const;
|
||||
double get_sp_x(const point *sp) const;
|
||||
int intersection_step() const { return current_state->intersection_scan; }
|
||||
const Gcalc_heap::Info *get_cur_pi() const
|
||||
{
|
||||
DBUG_ASSERT(!intersection_step());
|
||||
return current_state->pi;
|
||||
}
|
||||
const Gcalc_heap::Intersection_info *get_cur_ii() const
|
||||
{
|
||||
DBUG_ASSERT(intersection_step());
|
||||
return current_state->isc;
|
||||
}
|
||||
|
||||
private:
|
||||
Gcalc_heap *m_heap;
|
||||
Gcalc_heap::Info *m_cur_pi;
|
||||
slice_state state0, state1, state_s;
|
||||
slice_state *current_state;
|
||||
@ -382,7 +509,10 @@ private:
|
||||
}
|
||||
point *new_slice_point()
|
||||
{
|
||||
return (point *)new_item();
|
||||
point *new_point= (point *)new_item();
|
||||
new_point->dx.init();
|
||||
new_point->dy.init();
|
||||
return new_point;
|
||||
}
|
||||
point *new_slice(point *example);
|
||||
int arrange_event();
|
||||
@ -450,7 +580,6 @@ public:
|
||||
inline const Gcalc_scan_iterator::point *point() const { return sp; }
|
||||
inline const Gcalc_heap::Info *get_pi() const { return sp->pi; }
|
||||
inline gcalc_shape_info get_shape() const { return sp->get_shape(); }
|
||||
inline double get_x() const { return sp->x; }
|
||||
inline void restart(const Gcalc_scan_iterator *scan_i)
|
||||
{ sp= scan_i->get_b_slice(); }
|
||||
};
|
||||
|
@ -347,6 +347,10 @@ int Gcalc_result_receiver::add_point(double x, double y)
|
||||
buffer.q_append(prev_y);
|
||||
prev_x= x;
|
||||
prev_y= y;
|
||||
#ifndef NO_TESTING
|
||||
if (n_points == 53)
|
||||
printf("xxx\n");
|
||||
#endif /*NO_TESTING*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -488,6 +492,9 @@ int Gcalc_result_receiver::move_hole(uint32 dest_position, uint32 source_positio
|
||||
|
||||
Gcalc_operation_reducer::Gcalc_operation_reducer(size_t blk_size) :
|
||||
Gcalc_dyn_list(blk_size, sizeof(res_point)),
|
||||
#ifndef DBUG_OFF
|
||||
n_res_points(0),
|
||||
#endif /*DBUG_OFF*/
|
||||
m_res_hook((Gcalc_dyn_list::Item **)&m_result),
|
||||
m_first_active_thread(NULL)
|
||||
{}
|
||||
@ -514,9 +521,73 @@ Gcalc_operation_reducer(Gcalc_function *fn, modes mode, size_t blk_size) :
|
||||
}
|
||||
|
||||
|
||||
inline int Gcalc_operation_reducer::continue_range(active_thread *t,
|
||||
const Gcalc_heap::Info *p,
|
||||
int horiz_dir, double dx_dy)
|
||||
void Gcalc_operation_reducer::res_point::set(const Gcalc_scan_iterator *si)
|
||||
{
|
||||
if ((intersection_point= si->intersection_step()))
|
||||
ii= si->get_cur_ii();
|
||||
else
|
||||
pi= si->get_cur_pi();
|
||||
}
|
||||
|
||||
#ifndef NO_TESTING
|
||||
void call_checkpoint(int d)
|
||||
{
|
||||
printf("%d\n", d);
|
||||
}
|
||||
#endif /*NO_TESTING*/
|
||||
|
||||
Gcalc_operation_reducer::res_point *
|
||||
Gcalc_operation_reducer::add_res_point(Gcalc_function::shape_type type)
|
||||
{
|
||||
res_point *result= (res_point *)new_item();
|
||||
*m_res_hook= result;
|
||||
result->prev_hook= m_res_hook;
|
||||
m_res_hook= &result->next;
|
||||
result->type= type;
|
||||
#ifndef DBUG_OFF
|
||||
result->point_n= n_res_points++;
|
||||
#endif /*DBUG_OFF*/
|
||||
#ifndef NO_TESTING
|
||||
if (result->point_n == 74)
|
||||
call_checkpoint(74);
|
||||
#endif /*NO_TESTING*/
|
||||
return result;
|
||||
}
|
||||
|
||||
int Gcalc_operation_reducer::add_line(int incoming, active_thread *t,
|
||||
const Gcalc_scan_iterator::point *p)
|
||||
{
|
||||
line *l= new_line();
|
||||
if (!l)
|
||||
return 1;
|
||||
l->incoming= incoming;
|
||||
l->t= t;
|
||||
l->p= p;
|
||||
*m_lines_hook= l;
|
||||
m_lines_hook= &l->next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Gcalc_operation_reducer::add_poly_border(int incoming,
|
||||
active_thread *t, int prev_state, const Gcalc_scan_iterator::point *p)
|
||||
{
|
||||
poly_border *b= new_poly_border();
|
||||
if (!b)
|
||||
return 1;
|
||||
b->incoming= incoming;
|
||||
b->t= t;
|
||||
b->prev_state= prev_state;
|
||||
b->p= p;
|
||||
*m_poly_borders_hook= b;
|
||||
m_poly_borders_hook= &b->next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Gcalc_operation_reducer::continue_range(active_thread *t,
|
||||
const Gcalc_heap::Info *p,
|
||||
const Gcalc_heap::Info *p_next)
|
||||
{
|
||||
res_point *rp= add_res_point(t->rp->type);
|
||||
if (!rp)
|
||||
@ -527,15 +598,14 @@ inline int Gcalc_operation_reducer::continue_range(active_thread *t,
|
||||
rp->intersection_point= false;
|
||||
rp->pi= p;
|
||||
t->rp= rp;
|
||||
t->horiz_dir= horiz_dir;
|
||||
t->dx_dy= dx_dy;
|
||||
t->p1= p;
|
||||
t->p2= p_next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int Gcalc_operation_reducer::continue_i_range(active_thread *t,
|
||||
double x, double y,
|
||||
int horiz_dir, double dx_dy)
|
||||
const Gcalc_heap::Intersection_info *ii)
|
||||
{
|
||||
res_point *rp= add_res_point(t->rp->type);
|
||||
if (!rp)
|
||||
@ -544,11 +614,8 @@ inline int Gcalc_operation_reducer::continue_i_range(active_thread *t,
|
||||
rp->down= t->rp;
|
||||
t->rp->up= rp;
|
||||
rp->intersection_point= true;
|
||||
rp->x= x;
|
||||
rp->y= y;
|
||||
rp->ii= ii;
|
||||
t->rp= rp;
|
||||
t->horiz_dir= horiz_dir;
|
||||
t->dx_dy= dx_dy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -573,6 +640,9 @@ int Gcalc_operation_reducer::end_couple(active_thread *t0, active_thread *t1,
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_TESTING
|
||||
int ca_counter= 0;
|
||||
#endif /*NO_TESTING*/
|
||||
int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
{
|
||||
Gcalc_point_iterator pi(si);
|
||||
@ -587,8 +657,16 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
active_thread *bottom_threads= NULL;
|
||||
active_thread *eq_thread, *point_thread;;
|
||||
|
||||
#ifndef NO_TESTING
|
||||
if (ca_counter == 11522)
|
||||
call_checkpoint(89);
|
||||
#endif /*NO_TESTING*/
|
||||
m_fn->clear_state();
|
||||
/* Walk to the event, remembering what is needed. */
|
||||
#ifndef NO_TESTING
|
||||
if (si->get_event_position() == pi.point())
|
||||
printf("yyy\n");
|
||||
#endif /*NO_TESTING*/
|
||||
for (; pi.point() != si->get_event_position();
|
||||
++pi, cur_t_hook= (active_thread **) &(*cur_t_hook)->next)
|
||||
{
|
||||
@ -612,13 +690,13 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
case scev_point:
|
||||
{
|
||||
if (cur_t->enabled() &&
|
||||
continue_range(cur_t, events->pi, events->horiz_dir, events->dx_dy))
|
||||
continue_range(cur_t, events->pi, events->next_pi))
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
case scev_end:
|
||||
{
|
||||
if (cur_t->enabled() && end_line(cur_t, events->pi, si))
|
||||
if (cur_t->enabled() && end_line(cur_t, si))
|
||||
return 1;
|
||||
*cur_t_hook= cur_t->get_next();
|
||||
free_item(cur_t);
|
||||
@ -635,8 +713,7 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
else if (cur_t->enabled() || cur_t->get_next()->enabled())
|
||||
{
|
||||
/* Rare case when edges of a polygon coincide */
|
||||
if (end_line(cur_t->enabled() ? cur_t : cur_t->get_next(),
|
||||
events->pi, si))
|
||||
if (end_line(cur_t->enabled() ? cur_t : cur_t->get_next(), si))
|
||||
return 1;
|
||||
}
|
||||
*cur_t_hook= cur_t->get_next()->get_next();
|
||||
@ -647,6 +724,9 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
default:
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
#ifndef NO_TESTING
|
||||
goto testing;
|
||||
#endif /*NO_TESTING*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -773,7 +853,7 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
for (events= si->get_events(); events; events= events->get_next())
|
||||
m_fn->set_on_state(events->get_shape());
|
||||
|
||||
return m_fn->count() ? add_single_point(event_point, si) : 0;
|
||||
return m_fn->count() ? add_single_point(si) : 0;
|
||||
}
|
||||
|
||||
if (m_poly_borders)
|
||||
@ -783,6 +863,10 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
{
|
||||
poly_border *pb1, *pb2;
|
||||
pb1= m_poly_borders;
|
||||
#ifndef NO_TESTING
|
||||
if (!m_poly_borders->next)
|
||||
call_checkpoint(3);
|
||||
#endif /*NO_TESTING*/
|
||||
DBUG_ASSERT(m_poly_borders->next);
|
||||
|
||||
pb2= get_pair_border(pb1);
|
||||
@ -790,8 +874,7 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
m_poly_borders= pb1->get_next();
|
||||
if (connect_threads(pb1->incoming, pb2->incoming,
|
||||
pb1->t, pb2->t, pb1->p, pb2->p,
|
||||
prev_range, event_point, si,
|
||||
Gcalc_function::shape_polygon))
|
||||
prev_range, si, Gcalc_function::shape_polygon))
|
||||
return 1;
|
||||
|
||||
free_item(pb1);
|
||||
@ -809,8 +892,8 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
{
|
||||
if (connect_threads(m_lines->incoming, m_lines->get_next()->incoming,
|
||||
m_lines->t, m_lines->get_next()->t,
|
||||
m_lines->p, m_lines->get_next()->p, NULL,
|
||||
event_point, si, Gcalc_function::shape_line))
|
||||
m_lines->p, m_lines->get_next()->p,
|
||||
NULL, si, Gcalc_function::shape_line))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -819,11 +902,11 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
{
|
||||
if (cur_line->incoming)
|
||||
{
|
||||
if (end_line(cur_line->t, event_point, si))
|
||||
if (end_line(cur_line->t, si))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
start_line(cur_line->t, cur_line->p, event_point, si);
|
||||
start_line(cur_line->t, cur_line->p, si);
|
||||
}
|
||||
}
|
||||
free_list(m_lines);
|
||||
@ -834,28 +917,56 @@ int Gcalc_operation_reducer::count_slice(Gcalc_scan_iterator *si)
|
||||
if (bottom_threads)
|
||||
free_list(bottom_threads);
|
||||
|
||||
#ifndef NO_TESTING
|
||||
testing:
|
||||
{
|
||||
Gcalc_point_iterator x_pi(si);
|
||||
active_thread **x_cur_t_hook= &m_first_active_thread;
|
||||
int x_prev_state= 0;
|
||||
m_fn->save_states();
|
||||
m_fn->clear_state();
|
||||
if (ca_counter == /*11552*/90)
|
||||
call_checkpoint(10);
|
||||
for (; x_pi.point(); ++x_pi)
|
||||
{
|
||||
active_thread *cur_t= *x_cur_t_hook;
|
||||
if (cur_t->enabled() &&
|
||||
cur_t->rp->type == Gcalc_function::shape_polygon)
|
||||
x_prev_state^= 1;
|
||||
int ppb= m_fn->count();
|
||||
if (m_fn->get_shape_kind(x_pi.get_shape()) == Gcalc_function::shape_polygon)
|
||||
m_fn->invert_state(x_pi.get_shape());
|
||||
int ppa= m_fn->count();
|
||||
if (ppa != x_prev_state)
|
||||
{
|
||||
if (x_pi.point()->cmp_dx_dy(x_pi.point()->get_next()) != 0)
|
||||
call_checkpoint(21);
|
||||
}
|
||||
if (cur_t->enabled())
|
||||
{
|
||||
if (m_fn->get_shape_kind(x_pi.get_shape()) == Gcalc_function::shape_polygon)
|
||||
if (ppa == ppb)
|
||||
call_checkpoint(22);
|
||||
else
|
||||
if (ppa != 0 && ppb != 0)
|
||||
call_checkpoint(23);
|
||||
}
|
||||
x_cur_t_hook= (active_thread **) &(*x_cur_t_hook)->next;
|
||||
}
|
||||
m_fn->restore_states();
|
||||
}
|
||||
#endif /*NO_TESTING*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Gcalc_operation_reducer::add_single_point(const Gcalc_heap::Info *p,
|
||||
const Gcalc_scan_iterator *si)
|
||||
int Gcalc_operation_reducer::add_single_point(const Gcalc_scan_iterator *si)
|
||||
{
|
||||
res_point *rp= add_res_point(Gcalc_function::shape_point);
|
||||
if (!rp)
|
||||
return 1;
|
||||
rp->glue= rp->up= rp->down= NULL;
|
||||
if (p)
|
||||
{
|
||||
rp->intersection_point= false;
|
||||
rp->pi= p;
|
||||
}
|
||||
else
|
||||
{
|
||||
rp->intersection_point= true;
|
||||
rp->y= si->get_y();
|
||||
rp->x= si->get_events()->x;
|
||||
}
|
||||
rp->set(si);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -912,7 +1023,7 @@ int Gcalc_operation_reducer::connect_threads(
|
||||
int incoming_a, int incoming_b,
|
||||
active_thread *ta, active_thread *tb,
|
||||
const Gcalc_scan_iterator::point *pa, const Gcalc_scan_iterator::point *pb,
|
||||
active_thread *prev_range, const Gcalc_heap::Info *ev_p,
|
||||
active_thread *prev_range,
|
||||
const Gcalc_scan_iterator *si, Gcalc_function::shape_type s_t)
|
||||
{
|
||||
if (incoming_a && incoming_b)
|
||||
@ -929,18 +1040,8 @@ int Gcalc_operation_reducer::connect_threads(
|
||||
rpa->up= rpb->up= NULL;
|
||||
ta->rp->up= rpa;
|
||||
tb->rp->up= rpb;
|
||||
if (ev_p)
|
||||
{
|
||||
rpa->intersection_point= rpb->intersection_point= false;
|
||||
rpa->pi= rpb->pi= ev_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
rpa->intersection_point= rpb->intersection_point= true;
|
||||
rpa->x= rpb->x= si->get_events()->x;
|
||||
rpa->y= rpb->y= si->get_y();
|
||||
}
|
||||
|
||||
rpa->set(si);
|
||||
rpb->set(si);
|
||||
ta->rp= tb->rp= NULL;
|
||||
return 0;
|
||||
}
|
||||
@ -953,35 +1054,30 @@ int Gcalc_operation_reducer::connect_threads(
|
||||
return 1;
|
||||
rp0->glue= rp1;
|
||||
rp1->glue= rp0;
|
||||
if (ev_p)
|
||||
{
|
||||
rp0->intersection_point= rp1->intersection_point= false;
|
||||
rp0->pi= rp1->pi= ev_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
rp0->intersection_point= rp1->intersection_point= true;
|
||||
rp0->x= rp1->x= si->get_events()->x;
|
||||
rp0->y= rp1->y= si->get_y();
|
||||
}
|
||||
rp0->set(si);
|
||||
rp1->set(si);
|
||||
rp0->down= rp1->down= NULL;
|
||||
ta->rp= rp0;
|
||||
tb->rp= rp1;
|
||||
ta->horiz_dir= pa->horiz_dir;
|
||||
ta->dx_dy= pa->dx_dy;
|
||||
ta->p1= pa->pi;
|
||||
ta->p2= pa->next_pi;
|
||||
|
||||
tb->horiz_dir= pb->horiz_dir;
|
||||
tb->dx_dy= pb->dx_dy;
|
||||
tb->p1= pb->pi;
|
||||
tb->p2= pb->next_pi;
|
||||
|
||||
if (prev_range)
|
||||
{
|
||||
rp0->outer_poly= prev_range->thread_start;
|
||||
tb->thread_start= prev_range->thread_start;
|
||||
/* Chack if needed */
|
||||
ta->thread_start= prev_range->thread_start;
|
||||
}
|
||||
else
|
||||
{
|
||||
rp0->outer_poly= 0;
|
||||
ta->thread_start= rp0;
|
||||
/* Chack if needed */
|
||||
tb->thread_start= rp0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -991,20 +1087,18 @@ int Gcalc_operation_reducer::connect_threads(
|
||||
tb->rp= ta->rp;
|
||||
tb->thread_start= ta->thread_start;
|
||||
if (Gcalc_scan_iterator::point::
|
||||
compare_dx_dy(ta->horiz_dir, ta->dx_dy,
|
||||
pb->horiz_dir, pb->dx_dy) != 0)
|
||||
cmp_dx_dy(ta->p1, ta->p2, pb->pi, pb->next_pi) != 0)
|
||||
{
|
||||
if (ev_p ? continue_range(tb, ev_p, pb->horiz_dir, pb->dx_dy):
|
||||
continue_i_range(tb,
|
||||
si->get_events()->x, si->get_y(),
|
||||
pb->horiz_dir, pb->dx_dy))
|
||||
if (si->intersection_step() ?
|
||||
continue_i_range(tb, si->get_cur_ii()) :
|
||||
continue_range(tb, si->get_cur_pi(), pb->next_pi))
|
||||
#ifdef TMP_BLOCK
|
||||
continue_range(tb, si->get_cur_pi())
|
||||
#endif /*TMP_BLOCK*/
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
tb->horiz_dir= pb->horiz_dir;
|
||||
tb->dx_dy= pb->dx_dy;
|
||||
}
|
||||
tb->p1= pb->pi;
|
||||
tb->p2= pb->next_pi;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1012,33 +1106,21 @@ int Gcalc_operation_reducer::connect_threads(
|
||||
|
||||
int Gcalc_operation_reducer::start_line(active_thread *t,
|
||||
const Gcalc_scan_iterator::point *p,
|
||||
const Gcalc_heap::Info *ev_p,
|
||||
const Gcalc_scan_iterator *si)
|
||||
{
|
||||
res_point *rp= add_res_point(Gcalc_function::shape_line);
|
||||
if (!rp)
|
||||
return 1;
|
||||
rp->glue= rp->down= NULL;
|
||||
if (ev_p)
|
||||
{
|
||||
rp->intersection_point= false;
|
||||
rp->pi= ev_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
rp->intersection_point= true;
|
||||
rp->x= si->get_events()->x;
|
||||
rp->y= si->get_y();
|
||||
}
|
||||
rp->set(si);
|
||||
t->rp= rp;
|
||||
t->horiz_dir= p->horiz_dir;
|
||||
t->dx_dy= p->dx_dy;
|
||||
t->p1= p->pi;
|
||||
t->p2= p->next_pi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Gcalc_operation_reducer::end_line(active_thread *t,
|
||||
const Gcalc_heap::Info *ev_p,
|
||||
const Gcalc_scan_iterator *si)
|
||||
{
|
||||
DBUG_ASSERT(t->rp->type == Gcalc_function::shape_line);
|
||||
@ -1047,17 +1129,7 @@ int Gcalc_operation_reducer::end_line(active_thread *t,
|
||||
return 1;
|
||||
rp->glue= rp->up= NULL;
|
||||
rp->down= t->rp;
|
||||
if (ev_p)
|
||||
{
|
||||
rp->intersection_point= false;
|
||||
rp->pi= ev_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
rp->intersection_point= true;
|
||||
rp->x= si->get_events()->x;
|
||||
rp->y= si->get_y();
|
||||
}
|
||||
rp->set(si);
|
||||
t->rp->up= rp;
|
||||
t->rp= NULL;
|
||||
|
||||
@ -1071,6 +1143,11 @@ int Gcalc_operation_reducer::count_all(Gcalc_heap *hp)
|
||||
si.init(hp);
|
||||
while (si.more_points())
|
||||
{
|
||||
#ifndef NO_TESTING
|
||||
printf("Point %d\n", ++ca_counter);
|
||||
if (ca_counter == 12)
|
||||
call_checkpoint(10);
|
||||
#endif /*NO_TESTING*/
|
||||
if (si.step())
|
||||
return 1;
|
||||
if (count_slice(&si))
|
||||
@ -1094,8 +1171,9 @@ inline int Gcalc_operation_reducer::get_single_result(res_point *res,
|
||||
{
|
||||
if (res->intersection_point)
|
||||
{
|
||||
if (storage->single_point(float_to_coord(res->x),
|
||||
float_to_coord(res->y)))
|
||||
double x, y;
|
||||
res->ii->calc_xy(&x, &y);
|
||||
if (storage->single_point(x,y))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
@ -1105,6 +1183,9 @@ inline int Gcalc_operation_reducer::get_single_result(res_point *res,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_TESTING
|
||||
int pc_counter= 0;
|
||||
#endif /*NO_TESTING*/
|
||||
|
||||
int Gcalc_operation_reducer::get_result_thread(res_point *cur,
|
||||
Gcalc_result_receiver *storage,
|
||||
@ -1116,12 +1197,16 @@ int Gcalc_operation_reducer::get_result_thread(res_point *cur,
|
||||
double x, y;
|
||||
while (cur)
|
||||
{
|
||||
#ifndef NO_TESTING
|
||||
++pc_counter;
|
||||
if (pc_counter == 79)
|
||||
call_checkpoint(79);
|
||||
#endif /*NO_TESTING*/
|
||||
if (!glue_step)
|
||||
{
|
||||
if (cur->intersection_point)
|
||||
{
|
||||
x= float_to_coord(cur->x);
|
||||
y= float_to_coord(cur->y);
|
||||
cur->ii->calc_xy(&x, &y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -206,26 +206,37 @@ public:
|
||||
int get_result(Gcalc_result_receiver *storage);
|
||||
void reset();
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
int n_res_points;
|
||||
#endif /*DBUG_OFF*/
|
||||
class res_point : public Gcalc_dyn_list::Item
|
||||
{
|
||||
public:
|
||||
bool intersection_point;
|
||||
double x,y;
|
||||
int intersection_point;
|
||||
union
|
||||
{
|
||||
const Gcalc_heap::Info *pi;
|
||||
const Gcalc_heap::Intersection_info *ii;
|
||||
res_point *first_poly_node;
|
||||
};
|
||||
#ifdef TMP_BLOCK
|
||||
union
|
||||
{
|
||||
#endif /*TMP_BLOCK*/
|
||||
res_point *outer_poly;
|
||||
uint32 poly_position;
|
||||
#ifdef TMP_BLOCK
|
||||
};
|
||||
#endif /*TMP_BLOCK*/
|
||||
res_point *up;
|
||||
res_point *down;
|
||||
res_point *glue;
|
||||
Gcalc_function::shape_type type;
|
||||
union
|
||||
{
|
||||
const Gcalc_heap::Info *pi;
|
||||
res_point *first_poly_node;
|
||||
};
|
||||
union
|
||||
{
|
||||
res_point *outer_poly;
|
||||
uint32 poly_position;
|
||||
};
|
||||
Gcalc_dyn_list::Item **prev_hook;
|
||||
#ifndef DBUG_OFF
|
||||
int point_n;
|
||||
#endif /*DBUG_OFF*/
|
||||
void set(const Gcalc_scan_iterator *si);
|
||||
res_point *get_next() { return (res_point *)next; }
|
||||
};
|
||||
|
||||
@ -233,9 +244,9 @@ public:
|
||||
{
|
||||
public:
|
||||
res_point *rp;
|
||||
int horiz_dir;
|
||||
double dx_dy;
|
||||
res_point *thread_start;
|
||||
|
||||
const Gcalc_heap::Info *p1, *p2;
|
||||
res_point *enabled() { return rp; }
|
||||
active_thread *get_next() { return (active_thread *)next; }
|
||||
};
|
||||
@ -273,33 +284,9 @@ public:
|
||||
line *new_line() { return (line *) new_item(); }
|
||||
poly_border *new_poly_border() { return (poly_border *) new_item(); }
|
||||
int add_line(int incoming, active_thread *t,
|
||||
const Gcalc_scan_iterator::point *p)
|
||||
{
|
||||
line *l= new_line();
|
||||
if (!l)
|
||||
return 1;
|
||||
l->incoming= incoming;
|
||||
l->t= t;
|
||||
l->p= p;
|
||||
*m_lines_hook= l;
|
||||
m_lines_hook= &l->next;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const Gcalc_scan_iterator::point *p);
|
||||
int add_poly_border(int incoming, active_thread *t, int prev_state,
|
||||
const Gcalc_scan_iterator::point *p)
|
||||
{
|
||||
poly_border *b= new_poly_border();
|
||||
if (!b)
|
||||
return 1;
|
||||
b->incoming= incoming;
|
||||
b->t= t;
|
||||
b->prev_state= prev_state;
|
||||
b->p= p;
|
||||
*m_poly_borders_hook= b;
|
||||
m_poly_borders_hook= &b->next;
|
||||
return 0;
|
||||
}
|
||||
const Gcalc_scan_iterator::point *p);
|
||||
|
||||
protected:
|
||||
Gcalc_function *m_fn;
|
||||
@ -310,43 +297,29 @@ protected:
|
||||
res_point *result_heap;
|
||||
active_thread *m_first_active_thread;
|
||||
|
||||
res_point *add_res_point(Gcalc_function::shape_type type)
|
||||
{
|
||||
res_point *result= (res_point *)new_item();
|
||||
*m_res_hook= result;
|
||||
result->prev_hook= m_res_hook;
|
||||
m_res_hook= &result->next;
|
||||
result->type= type;
|
||||
return result;
|
||||
}
|
||||
|
||||
res_point *add_res_point(Gcalc_function::shape_type type);
|
||||
active_thread *new_active_thread() { return (active_thread *)new_item(); }
|
||||
|
||||
poly_instance *new_poly() { return (poly_instance *) new_item(); }
|
||||
|
||||
private:
|
||||
int start_line(active_thread *t, const Gcalc_scan_iterator::point *p,
|
||||
const Gcalc_heap::Info *ev_p, const Gcalc_scan_iterator *si);
|
||||
int end_line(active_thread *t, const Gcalc_heap::Info *ev_p,
|
||||
const Gcalc_scan_iterator *si);
|
||||
const Gcalc_scan_iterator *si);
|
||||
int end_line(active_thread *t, const Gcalc_scan_iterator *si);
|
||||
int connect_threads(int incoming_a, int incoming_b,
|
||||
active_thread *ta, active_thread *tb,
|
||||
const Gcalc_scan_iterator::point *pa,
|
||||
const Gcalc_scan_iterator::point *pb,
|
||||
active_thread *prev_range,
|
||||
const Gcalc_heap::Info *ev_p,
|
||||
const Gcalc_scan_iterator *si,
|
||||
Gcalc_function::shape_type s_t);
|
||||
int add_single_point(const Gcalc_heap::Info *p,
|
||||
const Gcalc_scan_iterator *si);
|
||||
int add_single_point(const Gcalc_scan_iterator *si);
|
||||
poly_border *get_pair_border(poly_border *b1);
|
||||
int continue_range(active_thread *t, const Gcalc_heap::Info *p,
|
||||
int horiz_dir, double dx_dy);
|
||||
int continue_i_range(active_thread *t, double x, double y,
|
||||
int horiz_dir, double dx_dy);
|
||||
const Gcalc_heap::Info *p_next);
|
||||
int continue_i_range(active_thread *t,
|
||||
const Gcalc_heap::Intersection_info *ii);
|
||||
int end_couple(active_thread *t0, active_thread *t1, const Gcalc_heap::Info *p);
|
||||
int add_single_point(const Gcalc_heap::Info *p);
|
||||
|
||||
int get_single_result(res_point *res, Gcalc_result_receiver *storage);
|
||||
int get_result_thread(res_point *cur, Gcalc_result_receiver *storage,
|
||||
int move_upward, res_point *first_poly_node);
|
||||
|
@ -867,7 +867,8 @@ int Item_func_spatial_rel::func_touches()
|
||||
if (cur_func)
|
||||
{
|
||||
area= scan_it.get_h() *
|
||||
((ti.rb()->x - ti.lb()->x) + (ti.rt()->x - ti.lt()->x));
|
||||
((scan_it.get_sp_x(ti.rb()) - scan_it.get_sp_x(ti.lb())) +
|
||||
(scan_it.get_sp_x(ti.rt()) - scan_it.get_sp_x(ti.lt())));
|
||||
if (area > GIS_ZERO)
|
||||
{
|
||||
result= 0;
|
||||
|
@ -2230,6 +2230,8 @@ bool Gis_geometry_collection::get_mbr(MBR *mbr, const char **end) const
|
||||
return 1;
|
||||
n_objects= uint4korr(data);
|
||||
data+= 4;
|
||||
if (n_objects == 0)
|
||||
return 1;
|
||||
|
||||
while (n_objects--)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user