/*! \brief Check if point is masked \param gs pointer to geosurf struct \param pt point coordinates (X,Y,Z) \return 1 masked \return 0 not masked */ int gs_point_is_masked(geosurf * gs, float *pt) { int vrow, vcol, drow, dcol; int retmask = 0, npts = 0; float p2[2]; if (!gs->curmask) { return (0); } vrow = Y2VROW(gs, pt[Y]); vcol = X2VCOL(gs, pt[X]); /* check right & bottom edges */ if (pt[X] == VCOL2X(gs, VCOLS(gs))) { /* right edge */ vcol -= 1; } if (pt[Y] == VROW2Y(gs, VROWS(gs))) { /* bottom edge */ vrow -= 1; } drow = VROW2DROW(gs, vrow); dcol = VCOL2DCOL(gs, vcol); if (BM_get(gs->curmask, dcol, drow)) { retmask |= MASK_TL; npts++; } dcol = VCOL2DCOL(gs, vcol + 1); if (BM_get(gs->curmask, dcol, drow)) { retmask |= MASK_TR; npts++; } drow = VROW2DROW(gs, vrow + 1); if (BM_get(gs->curmask, dcol, drow)) { retmask |= MASK_BR; npts++; } dcol = VCOL2DCOL(gs, vcol); if (BM_get(gs->curmask, dcol, drow)) { retmask |= MASK_BL; npts++; } if (npts != 1) { /* zero or masked */ return (retmask | npts); } p2[X] = VCOL2X(gs, vcol); p2[Y] = VROW2Y(gs, vrow + 1); switch (retmask) { case MASK_TL: if ((pt[X] - p2[X]) / VXRES(gs) > (pt[Y] - p2[Y]) / VYRES(gs)) { /* lower triangle */ return (0); } return (retmask | npts); case MASK_TR: return (retmask | npts); case MASK_BR: if ((pt[X] - p2[X]) / VXRES(gs) <= (pt[Y] - p2[Y]) / VYRES(gs)) { /* upper triangle */ return (0); } return (retmask | npts); case MASK_BL: return (retmask | npts); } /* Assume that if we get here it is an error */ return (0); }
/*! \brief ADD In gsd_surf, tmesh draws polys like so: <pre> -------------- | /| | / | | / | | / | | / | | / | | / | | / | | / | | / | | / | |/ | -------------- </pre> UNLESS the top right or bottom left point is masked, in which case a single triangle with the opposite diagonal is drawn. This case is not yet handled here & should only occur on edges. pt has X & Y coordinates in it, we interpolate Z here This could probably be much shorter, but not much faster. \return 1 if point is in view region \return otherwise 0 (if masked) */ int viewcell_tri_interp(geosurf * gs, typbuff * buf, Point3 pt, int check_mask) { Point3 p1, p2, p3; int offset, drow, dcol, vrow, vcol; float xmax, ymin, ymax, alpha; xmax = VCOL2X(gs, VCOLS(gs)); ymax = VROW2Y(gs, 0); ymin = VROW2Y(gs, VROWS(gs)); if (check_mask) { if (gs_point_is_masked(gs, pt)) { return (0); } } if (pt[X] < 0.0 || pt[Y] > ymax) { /* outside on left or top */ return (0); } if (pt[Y] < ymin || pt[X] > xmax) { /* outside on bottom or right */ return (0); } if (CONST_ATT == gs_get_att_src(gs, ATT_TOPO)) { pt[Z] = gs->att[ATT_TOPO].constant; return (1); } else if (MAP_ATT != gs_get_att_src(gs, ATT_TOPO)) { return (0); } vrow = Y2VROW(gs, pt[Y]); vcol = X2VCOL(gs, pt[X]); if (vrow < VROWS(gs) && vcol < VCOLS(gs)) { /*not on bottom or right edge */ if (pt[X] > 0.0 && pt[Y] < ymax) { /* not on left or top edge */ p1[X] = VCOL2X(gs, vcol + 1); p1[Y] = VROW2Y(gs, vrow); drow = VROW2DROW(gs, vrow); dcol = VCOL2DCOL(gs, vcol + 1); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p1[Z]); /* top right */ p2[X] = VCOL2X(gs, vcol); p2[Y] = VROW2Y(gs, vrow + 1); drow = VROW2DROW(gs, vrow + 1); dcol = VCOL2DCOL(gs, vcol); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p2[Z]); /* bottom left */ if ((pt[X] - p2[X]) / VXRES(gs) > (pt[Y] - p2[Y]) / VYRES(gs)) { /* lower triangle */ p3[X] = VCOL2X(gs, vcol + 1); p3[Y] = VROW2Y(gs, vrow + 1); drow = VROW2DROW(gs, vrow + 1); dcol = VCOL2DCOL(gs, vcol + 1); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p3[Z]); /* bottom right */ } else { /* upper triangle */ p3[X] = VCOL2X(gs, vcol); p3[Y] = VROW2Y(gs, vrow); drow = VROW2DROW(gs, vrow); dcol = VCOL2DCOL(gs, vcol); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p3[Z]); /* top left */ } return (Point_on_plane(p1, p2, p3, pt)); } else if (pt[X] == 0.0) { /* on left edge */ if (pt[Y] < ymax) { vrow = Y2VROW(gs, pt[Y]); drow = VROW2DROW(gs, vrow); offset = DRC2OFF(gs, drow, 0); GET_MAPATT(buf, offset, p1[Z]); drow = VROW2DROW(gs, vrow + 1); offset = DRC2OFF(gs, drow, 0); GET_MAPATT(buf, offset, p2[Z]); alpha = (VROW2Y(gs, vrow) - pt[Y]) / VYRES(gs); pt[Z] = LERP(alpha, p1[Z], p2[Z]); } else { /* top left corner */ GET_MAPATT(buf, 0, pt[Z]); } return (1); } else if (pt[Y] == gs->yrange) { /* on top edge, not a corner */ vcol = X2VCOL(gs, pt[X]); dcol = VCOL2DCOL(gs, vcol); GET_MAPATT(buf, dcol, p1[Z]); dcol = VCOL2DCOL(gs, vcol + 1); GET_MAPATT(buf, dcol, p2[Z]); alpha = (pt[X] - VCOL2X(gs, vcol)) / VXRES(gs); pt[Z] = LERP(alpha, p1[Z], p2[Z]); return (1); } } else if (vrow == VROWS(gs)) { /* on bottom edge */ drow = VROW2DROW(gs, VROWS(gs)); if (pt[X] > 0.0 && pt[X] < xmax) { /* not a corner */ vcol = X2VCOL(gs, pt[X]); dcol = VCOL2DCOL(gs, vcol); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p1[Z]); dcol = VCOL2DCOL(gs, vcol + 1); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p2[Z]); alpha = (pt[X] - VCOL2X(gs, vcol)) / VXRES(gs); pt[Z] = LERP(alpha, p1[Z], p2[Z]); return (1); } else if (pt[X] == 0.0) { /* bottom left corner */ offset = DRC2OFF(gs, drow, 0); GET_MAPATT(buf, offset, pt[Z]); return (1); } else { /* bottom right corner */ dcol = VCOL2DCOL(gs, VCOLS(gs)); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, pt[Z]); return (1); } } else { /* on right edge, not bottom corner */ dcol = VCOL2DCOL(gs, VCOLS(gs)); if (pt[Y] < ymax) { vrow = Y2VROW(gs, pt[Y]); drow = VROW2DROW(gs, vrow); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p1[Z]); drow = VROW2DROW(gs, vrow + 1); offset = DRC2OFF(gs, drow, dcol); GET_MAPATT(buf, offset, p2[Z]); alpha = (VROW2Y(gs, vrow) - pt[Y]) / VYRES(gs); pt[Z] = LERP(alpha, p1[Z], p2[Z]); return (1); } else { /* top right corner */ GET_MAPATT(buf, dcol, pt[Z]); return (1); } } return (0); }