// // Refine a grid into a TIN_TILgE with error < e // void refineTile(TIN_TILE *tt, double e, short delaunay, short useNodata) { BOOL complete; // is maxE < e complete = 0; TRIANGLE *t1, *t2, *t3, *s; int refineCount = 0; // Read points for initial two triangles into a file initTilePoints(tt,e,useNodata); // While there still is a triangle with max error > e while(PQ_extractMin(tt->pq, &s)){ // Triangles should no longer be marked for deletion since they // are being deleted from the PQ if(s->p1p2 == NULL && s->p1p3 == NULL && s->p2p3 == NULL){ printf(strcat("skipping deleted triangle: err=",ELEV_TYPE_PRINT_CHAR), s->maxErrorValue); fflush(stdout); assert(0); removeTri(s); } assert(s); refineCount++; // malloc the point with max error as it will become a corner R_POINT* maxError = (R_POINT*)malloc(sizeof(R_POINT)); assert(maxError); maxError->x = s->maxE->x; maxError->y = s->maxE->y; maxError->z = s->maxE->z; // Add point to the correct point pointer array assert(tt->bPointsCount < tt->ncols && tt->rPointsCount < tt->nrows && tt->bPointsCount < (tt->ncols * tt->nrows)-(tt->ncols + tt->nrows)); if(maxError->x == (tt->iOffset + tt->nrows-1) ){ tt->bPoints[tt->bPointsCount]=maxError; tt->bPointsCount++; } else if(maxError->y == (tt->jOffset + tt->ncols-1) ){ tt->rPoints[tt->rPointsCount]=maxError; tt->rPointsCount++; } else{ tt->points[tt->pointsCount]=maxError; tt->pointsCount++; } // Debug - print the point being added #ifdef REFINE_DEBUG { TRIANGLE *snext; R_POINT err = findError(s->maxE->x, s->maxE->y, s->maxE->z, s); printf("Point (%6d,%6d,%6d) error=%10ld \t", s->maxE->x, s->maxE->y, s->maxE->z, err ); printTriangleCoords(s); fflush(stdout); if(err != s->maxErrorValue){ printf("Died err= %ld maxE= %ld \n",err,s->maxErrorValue); exit(1); } PQ_min(tt->pq, &snext); assert(s->maxErrorValue >= snext->maxErrorValue); } #endif // Check for collinear points. We make the valid assumption that // MaxE cannot be collinear with > 1 tri int area12,area13,area23; area12 = areaSign(s->p1, s->p2, maxError); area13 = areaSign(s->p1, maxError, s->p3); area23 = areaSign(maxError, s->p2, s->p3); // If p1 p2 is collinear with MaxE if (!area12){ fixCollinear(s->p1,s->p2,s->p3,s,e,maxError,tt,delaunay); tt->numTris++; } else if (!area13){ fixCollinear(s->p1,s->p3,s->p2,s,e,maxError,tt,delaunay); tt->numTris++; } else if (!area23){ fixCollinear(s->p2,s->p3,s->p1,s,e,maxError,tt,delaunay); tt->numTris++; } else { // add three new triangles t1 = addTri(tt,s->p1, s->p2, maxError,s->p1p2,NULL,NULL); t2 = addTri(tt,s->p1, maxError, s->p3,t1,s->p1p3,NULL); t3 = addTri(tt,maxError, s->p2, s->p3,t1,t2,s->p2p3); DEBUG{triangleCheck(s,t1,t2,t3);} tt->numTris += 2; // create poinlists from the original tri (this will yeild the max error) distrPoints(t1,t2,t3,s,NULL,e,tt); DEBUG{checkPointList(t1);checkPointList(t2);checkPointList(t3);} // Enforce delaunay on three new edges of the new triangles if // specified if(delaunay){ // we enforce on the edge that does not have maxE as an // endpoint, so the 4th argument to enforceDelaunay should // always be the maxE point to s for that particular tri enforceDelaunay(t1,t1->p1,t1->p2,t1->p3,e,tt); enforceDelaunay(t2,t2->p1,t2->p3,t2->p2,e,tt); enforceDelaunay(t3,t3->p2,t3->p3,t3->p1,e,tt); } } // remove original tri removeTri(s); //DEBUG{printTin(tt);} extern int displayValid; displayValid = 0; } s = tt->t; // The number of points added is equal to the number of refine loops tt->numPoints += refineCount; /* The number of points should be equal to the sum of all points arrays (one center and possible 4 boundary). Since the arrays have overlap of corner points we subtract the overlaps */ int pts = 0; pts = tt->pointsCount + tt->rPointsCount + tt->bPointsCount - 1; if(tt->top != NULL) pts += tt->top->bPointsCount - 2; if(tt->left != NULL) pts += tt->left->rPointsCount - 2; //assert(tt->numPoints == pts); fix // Sort the point arrays for future use and binary searching qsort(tt->rPoints,tt->rPointsCount,sizeof(R_POINT*),(void *)QS_compPoints); qsort(tt->bPoints,tt->bPointsCount,sizeof(R_POINT*),(void *)QS_compPoints); qsort(tt->points,tt->pointsCount,sizeof(R_POINT*),(void *)QS_compPoints); // We are done with the pq PQ_free(tt->pq); }
/* Delete the min element; same as PQ_extractMin, but ignore the value extracted; return value: 1 if exists a min, 0 if not */ int PQ_deleteMin(PQueue* pq) { assert(pq && pq->elements); elemType dummy; return PQ_extractMin(pq, &dummy); }