IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 19, 2010, 6:32:46 PM (16 years ago)
Author:
bills
Message:

A skycell boundary transformed to chip coordinates can have 3 left edges. Deal with this by
changing the way we identify the corners to work with upper left, upper right, lower left and lower right
corners. When calculating the left and right boundaries deal up to 2 transitions

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/magic/remove/src/diffedpixels.c

    r27360 r27371  
    88static int xLeft(psPlane *pt, int y);
    99static int xRight(psPlane *pt, int y);
     10
     11#define  BL 0
     12#define  BR 1
     13#define  TL 2
     14#define  TR 3
    1015
    1116// Examine the set of diff skycells and compute the pixels that were
     
    9196        sf->diffedPixels->numCols, sf->diffedPixels->numRows);
    9297
    93     // convert corners of skycell to sky coordinates
     98    // convert corners of skycell to chip coordinates
    9499    // compute overlap with the chip using astrometry
    95100    psPlane pt[4];
     
    120125            streaksExit("", PS_EXIT_DATA_ERROR);
    121126        }
    122         pt[i].x = p.x;
    123         pt[i].y = p.y;
     127        pt[i].x = round(p.x);
     128        pt[i].y = round(p.y);
    124129    }
    125130
    126131    psFree(wcs);
    127132
    128     // put the corners in the desired order (see comments below)
     133    // Identify the bottom left, bottom right, top left, and top right corners
    129134    nameCorners(pt);
    130     psString type;
    131     if (pt[0].y < pt[2].y ) {
    132         type = "1";
    133     } else {
    134         type = "2";
    135     }
     135
    136136#ifdef DEBUG_PRINT
    137     fprintf(stderr, "\nSKYCELL %s Type: %s\n", fileName, type);
    138     for (int i=0; i<4; i++) {
    139         fprintf(stderr, "%f %f\n", pt[i].x, pt[i].y);
    140     }
     137    fprintf(stderr, "\nSKYCELL %s\n", fileName);
     138    fprintf(stderr, "BL %f %f\n", pt[BL].x, pt[BL].y);
     139    fprintf(stderr, "BR %f %f\n", pt[BR].x, pt[BR].y);
     140    fprintf(stderr, "TL %f %f\n", pt[TL].x, pt[TL].y);
     141    fprintf(stderr, "TR %f %f\n", pt[TR].x, pt[TR].y);
    141142#endif
    142     // Now set the touched pixels
    143     int ymin = fmax(0, pt[1].y );
    144     int ymax = fmin(pt[3].y + 0.5, sf->diffedPixels->numRows - 1);
     143
     144    int xmax = sf->diffedPixels->numCols - 1;
     145    int ymin;
     146    int ymax;
     147   
     148    if (pt[BL].y <= pt[BR].y) {
     149        ymin = fmax(0, pt[BL].y);
     150    } else {
     151        ymin = fmax(0, pt[BR].y);
     152    }
     153    if (pt[TR].y >= pt[TL].y) {
     154        ymax = fmin(pt[TR].y, sf->diffedPixels->numRows - 1);
     155    } else {
     156        ymax = fmin(pt[TL].y, sf->diffedPixels->numRows - 1);
     157    }
     158       
    145159#if (DEBUG_PRINT > 1)
     160    fprintf(stderr, "\nxmin: %d xmax: %d\n", 0, xmax);
    146161    fprintf(stderr, "\nymin: %d ymax: %d\n", ymin, ymax);
    147162#endif
     163
     164    // Now set the touched pixels
    148165    for (int y = ymin ; y <= ymax; y++) {
     166
    149167        int xleft  = xLeft(pt, y) - 1;
    150168        int xright = xRight(pt, y) + 1;
    151169
     170        if (xright < 0) {
     171            continue;
     172        }
     173        if (xleft > xmax) {
     174            continue;
     175        }
    152176        if (xleft < 0) {
    153177            xleft = 0;
    154178        }
    155         if (xleft > sf->diffedPixels->numCols) {
    156             continue;
    157         }
    158         if (xright < 0) {
    159             continue;
    160         }
    161         if (xright >= sf->diffedPixels->numCols) {
    162             xright = sf->diffedPixels->numCols - 1;
     179        if (xright > xmax) {
     180            xright = xmax;
    163181        }
    164182#if (DEBUG_PRINT > 1)
     
    189207{
    190208    double x_d;
    191     if (y < pt[0].y) {
    192         // left boundary is the line from pt 0 to pt 1
    193         x_d = xOfY(&pt[0], &pt[1], y);
    194     } else {
    195         // left boundary is the line from pt 0 to pt 3
    196         x_d = xOfY(&pt[0], &pt[3], y);
    197     }
     209
     210    if ((y <= pt[BL].y ) && ((pt[BL].y >= pt[BR].y))) {
     211        // left boundary is the line from bottom left to bottom right
     212        x_d = xOfY(&pt[BL], &pt[BR], y);
     213    } else if ( y <= pt[TL].y ) {
     214        // left boundary is the line from Bottom left to top left
     215        x_d = xOfY(&pt[BL], &pt[TL], y);
     216    } else {
     217        // left boundary is the line from top left to top right
     218        x_d= xOfY(&pt[TL], &pt[TR], y);
     219    }
     220
    198221    return (int) floor(x_d);
    199222}
     
    202225{
    203226    double x_d;
    204     if (y < pt[2].y) {
    205         // right boundary is the line from pt 1 to pt 2
    206         x_d = xOfY(&pt[1], &pt[2], y);
    207 
    208     } else {
    209         // right boundary is the line from pt 2 to pt 3
    210         x_d = xOfY(&pt[2], &pt[3], y);
     227    if ((y <= pt[BR].y) && (pt[BR].y > pt[BL].y)) {
     228        // right boundary is the line from Bottom right to Top right
     229        x_d = xOfY(&pt[BL], &pt[BR], y);
     230    } else if ( y<= pt[TR].y) {
     231        // right boundary is the line from Top left to top right
     232        x_d = xOfY(&pt[BR], &pt[TR], y);
     233    } else {
     234        x_d = xOfY(&pt[TL], &pt[TR], y);
    211235    }
    212236    return (int) ceil(x_d);
    213237}
    214 
    215 /*
    216  * To compute the overlap of a quadrilateral with a set of
    217  * points we transform the 4 corners to image coordinates
    218  * and name the 4 points of the quad
    219             pt 0 is left most (bottom most corner)
    220             pt 1 is bottom most (right most corner)
    221             pt 2 is right most (top most corner)
    222             pt 3 is top most (left most corner)
    223 
    224 * Then we can divide the quad into 3 regions A B and C based
    225 * on the y coordinate
    226 
    227 * (in the degenerate case of a rectangle aligned to the axes
    228 * we only have 1 region)
    229 * In each of the three regions A, B, and C the test for whether a
    230 * point is contained in the quad on scanline y is simply
    231 
    232         x >= xleft(y) x < xright(y)
    233 
    234 * where xleft(y) and xright(y) are the bounding lines at the given
    235 * y coordinate.
    236 
    237 The following diagrams show some examples. The 4 points are labeled 0 to 3
    238 The three regions are labeld A B and C, the boundaries between the regions
    239 ocur at pt0.y and pt2.y
    240 
    241 Type 1
    242 
    243                 3
    244                  C
    245          ---------------2           left boundary:  line 0_1 y < pt0.y
    246                  B                                  line 0_3 y >= pt0.y
    247           0--------------
    248                  A                  right boundary: line 1_2 y < pt2.y
    249                    1                                line 2_3 y >= pt2.y
    250 **************************
    251 
    252                 3
    253               C
    254         0----------------
    255               B
    256       ----------------2
    257               A
    258             1
    259 
    260 **************************
    261 If The left side corners have the same x we also have a Type 1
    262 
    263         3       2
    264 
    265             B
    266 
    267         0       1
    268 
    269 (region A and C are empty in the case where the points form a rectangle)
    270 */
    271 
    272 /*
    273     Name the corners
    274     The following algorithm works for points that form a quadrilateral
    275     I think it also works for the situation where 3 points are co-linear
    276     and we have a triangle, but that isn't important for our purposes
    277 
    278 */
    279238
    280239static void
    281240nameCorners(psPlane pt[4])
    282241{
    283     // sort points top to bottom
     242    // sort points top to bottom (in case of ties take favor rightmost)
    284243    int i;
    285244    int j;
    286245    for (i=0; i<4; i++) {
    287         for (j = 0; j < 4; j++) {
    288             if (i == j) continue;
    289             if (pt[i].y > pt[j].y) {
     246        for (j = i + 1; j < 4; j++) {
     247            if ((pt[j].y > pt[i].y) ||
     248                ((pt[j].y == pt[i].y) && (pt[j].x > pt[i].x))) {
    290249                psPlane tmpPt = pt[j];
    291250                pt[j] = pt[i];
     
    312271        tr = pt[0];
    313272    }
    314     int type = 0;
    315     int type3 = 0;
    316     if (round(tl.x) == round(bl.x)) {
    317         type3 = 1;
    318         if (tl.y <= tr.y) {
    319             type = 1;
    320         } else {
    321             type = 2;
    322         }
    323     } else if (tl.y >= tr.y) {
    324         type = 1;
    325     } else {
    326         type = 2;
    327     }
    328     if (type == 1) {
    329         pt[0] = bl;
    330         pt[1] = br;
    331         pt[2] = tr;
    332         pt[3] = tl;
    333     } else {
    334         pt[0] = tl;
    335         pt[1] = bl;
    336         pt[2] = br;
    337         pt[3] = tr;
    338     }
    339 
    340     // Now check the results match our requirements
    341     // pt3 is above pt0
    342     if (pt[3].y <= pt[0].y) {
    343         fprintf(stderr, "ERROR calculating diff overlap\n");
    344         fprintf(stderr, "pt[3].y (%f) <= pt[0].y (%f)\n", pt[3].y, pt[0].y);
    345         streaksExit("", PS_EXIT_PROG_ERROR);
    346     }
    347     // pt3 is above pt1
    348     if (pt[3].y <= pt[1].y) {
    349         fprintf(stderr, "ERROR calculating diff overlap\n");
    350         fprintf(stderr, "pt[3].y (%f) <= pt[1].y (%f)\n", pt[3].y, pt[1].y);
    351         streaksExit("", PS_EXIT_PROG_ERROR);
    352     }
    353     // pt2 is above pt1
    354     if (pt[2].y <= pt[1].y) {
    355         fprintf(stderr, "ERROR calculating diff overlap\n");
    356         fprintf(stderr, "pt[2].y (%f) <= pt[1].y (%f)\n", pt[2].x, pt[1].x);
    357         streaksExit("", PS_EXIT_PROG_ERROR);
    358     }
    359     // pt1 is to the right of pt0
    360     if (pt[1].x <= pt[0].x) {
    361         fprintf(stderr, "ERROR calculating diff overlap\n");
    362         fprintf(stderr, "pt[1].x (%f) <= pt[0].x (%f)\n", pt[1].x, pt[0].x);
    363         streaksExit("", PS_EXIT_PROG_ERROR);
    364     }
    365     // pt2 is to the right of pt0
    366     if (pt[2].x <= pt[0].x) {
    367         fprintf(stderr, "ERROR calculating diff overlap\n");
    368         fprintf(stderr, "pt[2].x (%f) <= pt[0].x (%f)\n", pt[2].x, pt[0].x);
    369         streaksExit("", PS_EXIT_PROG_ERROR);
    370     }
    371     // pt2 is to the right of pt3
    372     if (pt[2].x <= pt[3].x) {
    373         fprintf(stderr, "ERROR calculating diff overlap\n");
    374         fprintf(stderr, "pt[2].x (%f) <= pt[3].x (%f)\n", pt[2].x, pt[3].x);
    375         streaksExit("", PS_EXIT_PROG_ERROR);
    376     }
    377 
    378     // pt2 is below or at the same y as pt3
    379     // This can happen with some strange shapes. Accept this with type3
    380     // since our edge conditions are still satisfied
    381     if (!type3 && (pt[2].y > pt[3].y)) {
    382         fprintf(stderr, "ERROR calculating diff overlap\n");
    383         fprintf(stderr, "pt[2].y (%f) > pt[3].y (%f)\n", pt[2].y, pt[3].y);
    384         streaksExit("", PS_EXIT_PROG_ERROR);
    385     }
    386 }
     273    pt[BL] = bl;
     274    pt[BR] = br;
     275    pt[TL] = tl;
     276    pt[TR] = tr;
     277}
Note: See TracChangeset for help on using the changeset viewer.