再接上

shi_guoyuan 2014-05-05 12:47:54
#pragma warning(push)
#pragma warning( disable : 4312 )
b.child = ( RTREENODE *) tid;
#pragma warning(pop)

return RTreeAddBranch(root, &b, node, new_node);
}
assert (FALSE);
return 0;
}

static RTREELISTNODE * _RTreeNewListNode(void)
{
return (RTREELISTNODE *) malloc(sizeof(RTREELISTNODE));
}

static void _RTreeFreeListNode(RTREELISTNODE *p)
{
free(p);
}

static void _RTreeReInsert(RTREENODE *node, RTREELISTNODE **ne)
{
RTREELISTNODE *ln = _RTreeNewListNode();
ln->node = node;
ln->next = *ne;
*ne = ln;
}

static int _RTreeDeleteRect( RTREEMBR *mbr, void* tid, RTREENODE *node, RTREELISTNODE **ee)
{
int i;

assert(mbr && node && ee);
assert(node->level >= 0);

if (node->level > 0)
{
for (i = 0; i < NODECARD; i++)
{
if (node->branch[i].child && RTreeOverlap( mbr, &(node->branch[i].mbr )))
{
if (!_RTreeDeleteRect( mbr, tid, node->branch[i].child, ee ))
{
if (node->branch[i].child->count >= MINNODEFILL)
node->branch[i].mbr = RTreeNodeCover( node->branch[i].child );
else{
_RTreeReInsert(node->branch[i].child, ee);
RTreeDisconnectBranch(node, i);
}
return 0;
}
}
}
return 1;
}

#pragma warning(push)
#pragma warning( disable : 4312 )

for (i = 0; i < LEAFCARD; i++)
{
if ( node->branch[i].child && node->branch[i].child == (RTREENODE *) tid )
{
RTreeDisconnectBranch( node, i );
return 0;
}

}
#pragma warning(pop)

return 1;
}

static void _RTreeTabIn(int depth)
{
int i;
for(i=0; i<depth; i++){
}
}


static int _RTreeSearchRect( RTREENODE *node, RTREEMBR *mbr, PFNRTreeSearchCallback pfnSHCB, void* pfnParam)
{
int hitCount = 0;
int i;

assert(node && mbr);
assert(node->level >= 0);

if (node->level > 0)
{
for (i=0; i<NODECARD; i++){
if (node->branch[i].child && RTreeOverlap(mbr, &node->branch[i].mbr))
hitCount += _RTreeSearchRect(node->branch[i].child, mbr, pfnSHCB, pfnParam);
}
}
else
{
#pragma warning(push)
#pragma warning( disable : 4311 )
for (i=0; i<LEAFCARD; i++)
{
if (node->branch[i].child && RTreeOverlap(mbr, &node->branch[i].mbr))
{
hitCount++;
if(pfnSHCB && ! pfnSHCB((void*)node->branch[i].child, pfnParam) )
return hitCount;

}
}
#pragma warning(pop)
}
return hitCount;
}

void RTreeInitRect( RTREEMBR *mbr)
{
int i;
for (i=0; i<SIDES_NUMB; i++)
mbr->bound[i] = (REALTYPE) 0;
}

RTREEMBR RTreeNullRect(void)
{
RTREEMBR mbr;
int i;

mbr.bound[0] = (REALTYPE) 1;
mbr.bound[DIMS_NUMB] = (REALTYPE)-1;
for (i=1; i<DIMS_NUMB; i++)
mbr.bound[i] = mbr.bound[i+DIMS_NUMB] = (REALTYPE) 0;
return mbr;
}

void RTreePrintRect( RTREEMBR *mbr, int depth)
{
int i;

_RTreeTabIn(depth);
fprintf (stdout, "mbr:\n");
for (i = 0; i < DIMS_NUMB; i++)
{
_RTreeTabIn(depth+1);
fprintf (stdout, "%f\t%f\n", mbr->bound[i], mbr->bound[i + DIMS_NUMB]);
}
}


REALTYPE RTreeRectArea( RTREEMBR *mbr )
{
if (INVALID_RECT(mbr))
return (REALTYPE) 0;

return (mbr->bound[DIMS_NUMB] - mbr->bound[0]) * (mbr->bound[DIMS_NUMB+1] - mbr->bound[1]);
}


REALTYPE RTreeRectVolume( RTREEMBR *mbr )
{
int i;
REALTYPE vol = (REALTYPE) 1;

if (INVALID_RECT(mbr))
return (REALTYPE) 0;

for(i=0; i<DIMS_NUMB; i++)
vol *= (mbr->bound[i+DIMS_NUMB] - mbr->bound[i]);
assert(vol >= 0.0);
return vol;
}

const double UnitSphereVolumes[] = {
0.000000,
2.000000,
3.141593,
4.188790,
4.934802,
5.263789,
5.167713,
4.724766,
4.058712,
3.298509,
2.550164,
1.884104,
1.335263,
0.910629,
0.599265, /* dimension 14 */
0.381443,
0.235331,
0.140981, /* dimension 17 */
0.082146,
0.046622,
0.025807, /* dimension 20 */
};

#if DIMS_NUMB > 20
#error "not enough precomputed sphere volumes"
#endif

#define UnitSphereVolume UnitSphereVolumes[DIMS_NUMB]

REALTYPE RTreeRectSphericalVolume( RTREEMBR *mbr )
{
int i;
double sum_of_squares=0, radius;

if (INVALID_RECT(mbr))
return (REALTYPE) 0;

for (i=0; i<DIMS_NUMB; i++) {
double half_extent = (mbr->bound[i+DIMS_NUMB] - mbr->bound[i]) / 2;
sum_of_squares += half_extent * half_extent;
}
radius = sqrt(sum_of_squares);
return (REALTYPE)(pow(radius, DIMS_NUMB) * UnitSphereVolume);
}

REALTYPE RTreeRectSurfaceArea( RTREEMBR *mbr )
{
int i, j;
REALTYPE sum = (REALTYPE) 0;

if (INVALID_RECT(mbr))
return (REALTYPE) 0;

for (i=0; i<DIMS_NUMB; i++) {
REALTYPE face_area = (REALTYPE)1;
for (j=0; j<DIMS_NUMB; j++)

if(i != j) {
REALTYPE j_extent = mbr->bound[j+DIMS_NUMB] - mbr->bound[j];
face_area *= j_extent;
}
sum += face_area;
}
return 2 * sum;
}

RTREEMBR RTreeCombineRect( RTREEMBR *rc1, RTREEMBR *rc2 )
{
int i, j;
RTREEMBR new_rect;

assert(rc1 && rc2);

if (INVALID_RECT(rc1))
return *rc2;

if (INVALID_RECT(rc2))
return *rc1;

for (i = 0; i < DIMS_NUMB; i++)
{
new_rect.bound[i] = MIN(rc1->bound[i], rc2->bound[i]);
j = i + DIMS_NUMB;
new_rect.bound[j] = MAX(rc1->bound[j], rc2->bound[j]);
}
return new_rect;
}

int RTreeOverlap( RTREEMBR *rc1, RTREEMBR *rc2)
{
int i, j;
assert(rc1 && rc2);

for (i=0; i<DIMS_NUMB; i++)
{
j = i + DIMS_NUMB;

if (rc1->bound[i] > rc2->bound[j] || rc2->bound[i] > rc1->bound[j])
return FALSE;
}
return TRUE;
}

int RTreeContained( RTREEMBR *r, RTREEMBR *s)
{
int i, j, result;
assert(r && s);

if (INVALID_RECT(r))
return TRUE;

if (INVALID_RECT(s))
return FALSE;

result = TRUE;
for (i = 0; i < DIMS_NUMB; i++)
{
j = i + DIMS_NUMB;
result = result && r->bound[i] >= s->bound[i] && r->bound[j] <= s->bound[j];
}
return result;
}

void RTreeSplitNode(HRTREEROOT root, RTREENODE *node, RTREEBRANCH *br, RTREENODE **new_node)
{
RTREEPARTITION *p;
int level;
assert(node && br);

level = node->level;
_RTreeGetBranches(root, node, br);
p = &root->Partitions[0];
_RTreeMethodZero(root, p, (level>0 ? MINNODEFILL : MINLEAFFILL));
*new_node = RTreeNewNode();
(*new_node)->level = node->level = level;
_RTreeLoadNodes(root, node, *new_node, p);

assert(node->count+(*new_node)->count == p->total);
}
void RTreeInitNode( RTREENODE *node )
{
int i;
node->count = 0;
node->level = -1;
for (i = 0; i < MAXCARD; i++)
_RTreeInitBranch(&(node->branch[i]));
}
RTREENODE *RTreeNewNode(void)
{
RTREENODE *node = (RTREENODE*) malloc(sizeof(RTREENODE));
assert(node);
RTreeInitNode(node);
return node;
}

void RTreeFreeNode( RTREENODE *node )
{
assert(node);
free(node);
}
void RTreePrintNode( RTREENODE *node, int depth )
{
int i;
assert(node);

_RTreeTabIn(depth);
fprintf (stdout, "node");

if (node->level == 0)
fprintf (stdout, " LEAF");
else if (node->level > 0)
fprintf (stdout, " NONLEAF");
else
fprintf (stdout, " TYPE=?");

#pragma warning(push) /* C4311 */
#pragma warning( disable : 4311 )
fprintf (stdout, " level=%d count=%d address=%o\n", node->level, node->count, (unsigned int) node);

for (i=0; i<node->count; i++)
{
if(node->level == 0) {
fprintf (stdout, "\t%ld: data = %ld\n", i, (unsigned int)node->branch[i].child);
}
else {
_RTreeTabIn(depth);
fprintf (stdout, "branch %d\n", i);
_RTreePrintBranch(&node->branch[i], depth+1);
}
}
#pragma warning(pop)
}

RTREEMBR RTreeNodeCover( RTREENODE *node )
{
int i, first_time=1;
RTREEMBR mbr;
assert(node);

RTreeInitRect(&mbr);

for (i = 0; i < MAXKIDS(node); i++)
{
if (node->branch[i].child)
{
if (first_time)
{
mbr = node->branch[i].mbr;
first_time = 0;
}
else
mbr = RTreeCombineRect(&mbr, &(node->branch[i].mbr));
}
}
return mbr;
}

int RTreePickBranch( RTREEMBR *mbr, RTREENODE *node)
{
RTREEMBR *r;
int i, first_time = 1;
REALTYPE increase, bestIncr=(REALTYPE)-1, area, bestArea=0;
int best=0;
RTREEMBR tmp_rect;
assert(mbr && node);

for (i=0; i<MAXKIDS(node); i++)
{
if (node->branch[i].child)
{
r = &node->branch[i].mbr;
area = RTreeRectSphericalVolume(r);
tmp_rect = RTreeCombineRect(mbr, r);
increase = RTreeRectSphericalVolume(&tmp_rect) - area;
if (increase < bestIncr || first_time)
{
best = i;
bestArea = area;
bestIncr = increase;
first_time = 0;
}
else if (increase == bestIncr && area < bestArea)
{
best = i;
bestArea = area;
bestIncr = increase;
}
}
}
return best;
}

int RTreeAddBranch(HRTREEROOT root, RTREEBRANCH *br, RTREENODE *node, RTREENODE **new_node)
{
int i;
assert(br && node);

if (node->count < MAXKIDS(node))
{
for (i = 0; i < MAXKIDS(node); i++)
{
if (node->branch[i].child == NULL)
{
node->branch[i] = *br;
node->count++;
break;
}
}
return 0;
}

assert(new_node);
RTreeSplitNode(root, node, br, new_node);

return 1;
}
void RTreeDisconnectBranch( RTREENODE *node, int i )
{
assert(node && i>=0 && i<MAXKIDS(node));
assert(node->branch[i].child);

_RTreeInitBranch(&(node->branch[i]));
node->count--;
}

void RTreeDestroyNode ( RTREENODE *node )
{
int i;

if (node->level > 0)
{
for ( i = 0; i < NODECARD; i++)
{
if ( node->branch[i].child )
RTreeDestroyNode ( node->branch[i].child );
}
}

RTreeFreeNode( node );
}
HRTREEROOT RTreeCreate(PFNRTreeSearchCallback pfnSearchCallback)
{
RTREEROOT * root = (RTREEROOT*) malloc(sizeof(RTREEROOT));
assert(root);
root->root_node = RTreeNewNode();
assert(root->root_node);
root->root_node->level = 0;
root->pfnCallback = pfnSearchCallback;
return root;
}

void RTreeDestroy(HRTREEROOT root)
{
RTreeDestroyNode (root->root_node);
root->root_node = 0;
free(root);
}

int RTreeSearch(HRTREEROOT root, RTREEMBR *mbr, void* pfnSearchCallbackParam)
{
return _RTreeSearchRect(root->root_node, mbr, root->pfnCallback, pfnSearchCallbackParam);
}

int RTreeInsert(HRTREEROOT root, RTREEMBR *mbr, void* tid, int level)
{
#ifdef _DEBUG
int i;
#endif

RTREENODE *newroot;
RTREENODE *newnode;
RTREEBRANCH b;
...全文
72 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧