Changeset 18317
- Timestamp:
- Jun 24, 2008, 4:15:46 PM (18 years ago)
- Location:
- trunk/psLib/src/types
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/types/psTree.c
r18174 r18317 294 294 } 295 295 296 static void treePrint(FILE *fptr, const psTreeNode *node, int level) 296 // Print a representation of the node; called recursively 297 static void treeNodePrint(FILE *fptr, // File pointer to which to print 298 const psTreeNode *node, // Node to print 299 int level // Level at which to print 300 ) 297 301 { 298 302 long index = node->index; // Index of node … … 322 326 if (node->left && node->right) { 323 327 fprintf(fptr, " ==> %lf\n", tree->division[index]); 324 tree Print(fptr, node->left, level);325 tree Print(fptr, node->right, level);328 treeNodePrint(fptr, node->left, level); 329 treeNodePrint(fptr, node->right, level); 326 330 return; 327 331 } … … 354 358 PS_ASSERT_TREE_NON_NULL(tree, ); 355 359 356 tree Print(fptr, tree->root, 0);360 treeNodePrint(fptr, tree->root, 0); 357 361 return; 358 362 } … … 375 379 376 380 // Returns the square of the distance between a point on the tree and an aribtary point 377 static inline double treeContentDistance(const psTree *tree, long index, const psVector *coords) 381 static inline double treeContentDistance(const psTree *tree, // Tree of interest 382 long index, // Index of point on tree 383 const psVector *coords // Coordinates of interest 384 ) 378 385 { 379 386 int dim = tree->dim; // Dimensionality … … 418 425 419 426 // Returns whether the designated leaf contains an arbitrary point 420 static inline bool treeBranchInside(const psTree *tree, long index, const psVector *coords) 427 static inline bool treeBranchInside(const psTree *tree, // Tree of interest 428 long index, // Index of leaf on tree 429 const psVector *coords // Coordinates of interest 430 ) 421 431 { 422 432 int dim = tree->dim; // Dimensionality … … 433 443 434 444 // Search a leaf node for a closer point 435 static inline void treeLeafSearch (long *bestIndex,436 double *bestDistance,437 const psTree *tree,438 const psTreeNode *leaf,439 const psVector *coords440 )445 static inline void treeLeafSearchNearest(long *bestIndex, // Index of closest point 446 double *bestDistance, // Distance to closest point 447 const psTree *tree, // Tree of interest 448 const psTreeNode *leaf, // Leaf to search 449 const psVector *coords // Coordinates of interest 450 ) 441 451 { 442 452 for (int i = 0; i < leaf->num; i++) { … … 452 462 453 463 454 455 464 // Given an arbitrary point, return the index of the nearest neighbour 456 465 long psTreeNearest(const psTree *tree, const psVector *coords) … … 467 476 long bestIndex = -1; // Index of best point 468 477 double bestDistance = INFINITY; // Distance to best point 469 treeLeafSearch (&bestIndex, &bestDistance, tree, leaf, coords);478 treeLeafSearchNearest(&bestIndex, &bestDistance, tree, leaf, coords); 470 479 471 480 // Work up from the leaf containing the point of interest, and for each in turn, search down the other … … 494 503 } 495 504 // Leaf node 496 treeLeafSearch (&bestIndex, &bestDistance, tree, node, coords);505 treeLeafSearchNearest(&bestIndex, &bestDistance, tree, node, coords); 497 506 work->data[workIndex] = NULL; 498 507 workIndex--; … … 504 513 505 514 return bestIndex; 515 } 516 517 // Search a leaf node for points within radius squared 518 static inline long treeLeafSearchWithin(double radius2, // Radius squared to search 519 const psTree *tree, // Tree of interest 520 const psTreeNode *leaf, // Leaf to search 521 const psVector *coords // Coordinates of interest 522 ) 523 { 524 long num = 0; // Number within circle 525 for (int i = 0; i < leaf->num; i++) { 526 long index = leaf->contents[i]; // Index of point 527 double distance = treeContentDistance(tree, index, coords); // Distance to point 528 if (distance < radius2) { 529 num++; 530 } 531 } 532 return num; 533 } 534 535 // Given an arbitrary point and a matching radius, return the number of points within that radius 536 long psTreeWithin(const psTree *tree, const psVector *coords, double radius) 537 { 538 #if 1 // Might be in a tight loop 539 PS_ASSERT_TREE_NON_NULL(tree, -1); 540 PS_ASSERT_VECTOR_NON_NULL(coords, -1); 541 PS_ASSERT_VECTOR_TYPE(coords, PS_TYPE_F64, -1); 542 PS_ASSERT_VECTOR_SIZE(coords, (long)tree->dim, -1); 543 #endif 544 545 radius *= radius; // We work with the radius-squared 546 long num = 0; // Number of points in circle 547 548 // This is essentially the same as psTreeNearest, except we're not allowed to prune 549 550 // Find the closest point in the leaf that contains the point of interest 551 psTreeNode *leaf = psTreeLeaf(tree, coords); // Leaf containing the point of interest 552 num += treeLeafSearchWithin(radius, tree, leaf, coords); 553 554 psArray *work = psArrayAlloc(tree->numNodes); // Work queue 555 while (leaf->up) { 556 psTreeNode *up = leaf->up; // Parent node 557 558 long workIndex = 0; 559 work->data[workIndex] = (leaf == up->left ? up->right : up->left); // The other node 560 while (workIndex >= 0) { 561 psTreeNode *node = work->data[workIndex]; 562 if (node->left) { 563 // Branch node 564 work->data[workIndex] = node->right; 565 work->data[++workIndex] = node->left; 566 continue; 567 } 568 // Leaf node 569 num += treeLeafSearchWithin(radius, tree, node, coords); 570 work->data[workIndex] = NULL; 571 workIndex--; 572 } 573 574 leaf = up; 575 } 576 psFree(work); 577 578 return num; 579 } 580 581 // Search a leaf node for any points within radius squared 582 static inline bool treeLeafSearchWithinAny(double radius2, // Radius squared to search 583 const psTree *tree, // Tree of interest 584 const psTreeNode *leaf, // Leaf to search 585 const psVector *coords // Coordinates of interest 586 ) 587 { 588 for (int i = 0; i < leaf->num; i++) { 589 long index = leaf->contents[i]; // Index of point 590 double distance = treeContentDistance(tree, index, coords); // Distance to point 591 if (distance < radius2) { 592 return true; 593 } 594 } 595 return false; 596 } 597 598 // Given an arbitrary point and a matching radius, return whether there are any points within that radius 599 bool psTreeWithinAny(const psTree *tree, const psVector *coords, double radius) 600 { 601 #if 1 // Might be in a tight loop 602 PS_ASSERT_TREE_NON_NULL(tree, false); 603 PS_ASSERT_VECTOR_NON_NULL(coords, false); 604 PS_ASSERT_VECTOR_TYPE(coords, PS_TYPE_F64, false); 605 PS_ASSERT_VECTOR_SIZE(coords, (long)tree->dim, false); 606 #endif 607 608 radius *= radius; // We work with the radius-squared 609 610 // This is essentially the same as psTreeWithin, except we can bail as soon as we find something 611 612 // Find the closest point in the leaf that contains the point of interest 613 psTreeNode *leaf = psTreeLeaf(tree, coords); // Leaf containing the point of interest 614 if (treeLeafSearchWithinAny(radius, tree, leaf, coords)) { 615 return true; 616 } 617 618 psArray *work = psArrayAlloc(tree->numNodes); // Work queue 619 while (leaf->up) { 620 psTreeNode *up = leaf->up; // Parent node 621 622 long workIndex = 0; 623 work->data[workIndex] = (leaf == up->left ? up->right : up->left); // The other node 624 while (workIndex >= 0) { 625 psTreeNode *node = work->data[workIndex]; 626 if (node->left) { 627 // Branch node 628 work->data[workIndex] = node->right; 629 work->data[++workIndex] = node->left; 630 continue; 631 } 632 // Leaf node 633 if (treeLeafSearchWithinAny(radius, tree, node, coords)) { 634 // Clear out the work queue 635 memset(work->data, 0, (workIndex + 1) * sizeof(void)); 636 psFree(work); 637 return true; 638 } 639 work->data[workIndex] = NULL; 640 workIndex--; 641 } 642 643 leaf = up; 644 } 645 psFree(work); 646 647 return false; 506 648 } 507 649 -
trunk/psLib/src/types/psTree.h
r18145 r18317 89 89 ); 90 90 91 /// Return the number of points within some radius of given coordinates 92 long psTreeWithin(const psTree *tree, ///< Tree 93 const psVector *coords, ///< Coordinates of interest 94 double radius ///< Radius of interest 95 ); 96 97 /// Return whether there are any points within some radius of given coordinates 98 bool psTreeWithinAny(const psTree *tree, ///< Tree 99 const psVector *coords, ///< Coordinates of interest 100 double radius ///< Radius of interest 101 ); 102 91 103 /// Return the coordinates of a point in the tree, specified by its index 92 104 psVector *psTreeCoords(psVector *out, ///< Output vector, or NULL
Note:
See TracChangeset
for help on using the changeset viewer.
