IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 28225


Ignore:
Timestamp:
Jun 4, 2010, 2:23:58 PM (16 years ago)
Author:
Paul Price
Message:

Fix multiple problems:

  1. Some functions were not pruning, hence were searching EVERY point (exactly what we're trying to avoid).
  2. Distance to branch was not considering the ra=0 boundary.
  3. Was passing psVectorAppend a long that it was reading as psS64, which is wrong when sizeof(long) != sizeof(psS64), e.g., on 32-bit machines.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/types/psTree.c

    r25256 r28225  
    342342        fprintf(fptr, " ");
    343343    }
    344     fprintf(fptr, "(");
    345344    for (int i = 0; i < node->num; i++) {
     345        fprintf(fptr, "%ld=(",node->contents[i]);
    346346        psF64 *coords = tree->data->F64[node->contents[i]]; // Coordinates
    347347        for (int j = 0; j < dim; j++) {
     
    351351            }
    352352        }
    353         fprintf(fptr, ")");
    354         if (i < node->num - 1) {
    355             fprintf(fptr, " (");
    356         }
     353        fprintf(fptr, ") ");
    357354    }
    358355    fprintf(fptr, "\n");
     
    451448}
    452449
     450static inline double sin2diff(double coord1, double coord2)
     451{
     452    double sinDiff = sin(coord1 - coord2);
     453    return PS_SQR(sinDiff);
     454}
     455
    453456// Returns the square of the distance between a leaf and an arbitrary point
    454457static inline double treeBranchDistance(const psTree *tree, long index, const psVector *coords)
     
    456459    int dim = tree->dim;                // Dimensionality
    457460    double distance = 0.0;              // Distance to box
    458     for (int i = 0; i < dim; i++) {
    459         double minDiff = tree->min->F64[index][i] - coords->data.F64[i];
    460         if (minDiff > 0) {
    461             switch (tree->type) {
    462               case PS_TREE_EUCLIDEAN:
     461    switch (tree->type) {
     462      case PS_TREE_EUCLIDEAN:
     463        for (int i = 0; i < dim; i++) {
     464            double minDiff = tree->min->F64[index][i] - coords->data.F64[i];
     465            if (minDiff > 0) {
    463466                distance += PS_SQR(minDiff);
    464                 break;
    465               case PS_TREE_SPHERICAL: {
    466                   double sinDiff = sin(minDiff / 2.0);
    467                   distance += PS_SQR(sinDiff);
    468                   break;
     467                continue;
     468            }
     469            double maxDiff = coords->data.F64[i] - tree->max->F64[index][i];
     470            if (maxDiff > 0) {
     471                distance += PS_SQR(maxDiff);
     472                continue;
     473            }
     474        }
     475        break;
     476      case PS_TREE_SPHERICAL: {
     477          double ra = coords->data.F64[0], dec = coords->data.F64[1];                 // Coords of interest
     478          double raMin = tree->min->F64[index][0], raMax = tree->max->F64[index][0]; // RA bounds
     479          double decMin = tree->min->F64[index][1], decMax = tree->max->F64[index][1]; // Dec bounds
     480
     481          double raDist = 0.0;
     482          if (ra < raMin || ra > raMax) {
     483              double ra1 = sin2diff(ra, raMin);
     484              double ra2 = sin2diff(ra + 2.0 * M_PI, raMin);
     485              raDist = PS_MIN(ra1, ra2);
     486              double ra3 = sin2diff(ra, raMax);
     487              if (ra3 < raDist) {
     488                  raDist = ra3;
    469489              }
    470               default:
    471                 psAbort("Unrecognised type: %x", tree->type);
    472             }
    473             continue;
    474         }
    475         double maxDiff = coords->data.F64[i] - tree->max->F64[index][i];
    476         if (maxDiff > 0) {
    477             switch (tree->type) {
    478               case PS_TREE_EUCLIDEAN:
    479                 distance += PS_SQR(maxDiff);
    480                 break;
    481               case PS_TREE_SPHERICAL: {
    482                   double sinDiff = sin(maxDiff / 2.0);
    483                   distance += PS_SQR(sinDiff);
    484                   break;
     490              double ra4 = sin2diff(ra + 2.0 * M_PI, raMax);
     491              if (ra4 < raDist) {
     492                  raDist = ra4;
    485493              }
    486               default:
    487                 psAbort("Unrecognised type: %x", tree->type);
    488             }
    489             continue;
    490         }
     494          }
     495
     496          double decDist = 0.0;
     497          if (dec < decMin || dec > decMax) {
     498              double dec1 = sin2diff(dec, decMin);
     499              double dec2 = sin2diff(dec, decMax);
     500              decDist = PS_MIN(dec1, dec2);
     501          }
     502          break;
     503      }
     504      default:
     505        psAbort("Unrecognised type: %x", tree->type);
    491506    }
    492507    return distance;
     
    653668    long num = 0;                       // Number of points in circle
    654669
    655     // This is essentially the same as psTreeNearest, except we're not allowed to prune
     670    // This is essentially the same as psTreeNearest
    656671
    657672    // Find the closest point in the leaf that contains the point of interest
     
    667682        while (workIndex >= 0) {
    668683            psTreeNode *node = work->data[workIndex];
     684            if (treeBranchDistance(tree, node->index, coords) > distance) {
     685                // No need to investigate
     686                work->data[workIndex] = NULL;
     687                workIndex--;
     688                continue;
     689            }
    669690            if (node->left) {
    670691                // Branch node
     
    696717{
    697718    for (int i = 0; i < leaf->num; i++) {
    698         long index = leaf->contents[i]; // Index of point
     719        psS64 index = leaf->contents[i]; // Index of point
    699720        if (treeContentDistance(tree, index, coords) < distance) {
    700721            psVectorAppend(result, index);
     
    720741    psVector *result = psVectorAllocEmpty(4, PS_TYPE_S64); // Indices of points within match radius
    721742
    722     // This is essentially the same as psTreeNearest, except we're not allowed to prune
     743    // This is essentially the same as psTreeNearest, except pruning based on the search radius
    723744
    724745    // Find the closest point in the leaf that contains the point of interest
     
    734755        while (workIndex >= 0) {
    735756            psTreeNode *node = work->data[workIndex];
     757            if (treeBranchDistance(tree, node->index, coords) > distance) {
     758                // No need to investigate
     759                work->data[workIndex] = NULL;
     760                workIndex--;
     761                continue;
     762            }
    736763            if (node->left) {
    737764                // Branch node
     
    801828        while (workIndex >= 0) {
    802829            psTreeNode *node = work->data[workIndex];
     830            if (treeBranchDistance(tree, node->index, coords) > distance) {
     831                // No need to investigate
     832                work->data[workIndex] = NULL;
     833                workIndex--;
     834                continue;
     835            }
    803836            if (node->left) {
    804837                // Branch node
Note: See TracChangeset for help on using the changeset viewer.