📄 monotriangulation.cc
字号:
{ if(compV2InY(inc_array[inc_current], dec_array[i]) <= 0) rChain.processNewVertex(dec_array[i], pStream); else break; } rChain.outputFan(inc_array[inc_current], pStream); monoTriangulationRec(dec_array[i-1], botVertex, inc_chain, inc_current, dec_chain, i, pStream); } else /*compV2InY(inc_array[inc_current], dec_array[dec_current]) > 0*/ { reflexChain rChain(20, 1); rChain.processNewVertex(topVertex, pStream); for(i=inc_current; i<inc_nVertices; i++) { if(compV2InY(inc_array[i], dec_array[dec_current]) >0) rChain.processNewVertex(inc_array[i], pStream); else break; } rChain.outputFan(dec_array[dec_current], pStream); monoTriangulationRec(inc_array[i-1], botVertex, inc_chain, i, dec_chain, dec_current, pStream); } }/*end case neither is empty*/} /* the name here assumes that the polygon is Y-monotone, but *this function also works for X-monotone polygons. * a monotne polygon consists of two extrem verteices: topVertex and botVertex, and *two monotone chains: inc_chain, and dec_chain. The edges of the increasing chain (inc_chain) *is ordered by following pointer: next, while the edges of the decreasing chain (dec_chain) *is ordered by following pointer: prev * inc_index index the vertex which is the toppest of the inc_chain which we are handling currently. * dec_index index the vertex which is the toppest of the dec_chain which we are handling currently. */void monoTriangulationRec(directedLine* inc_chain, Int inc_index, directedLine* dec_chain, Int dec_index, directedLine* topVertex, Int top_index, directedLine* botVertex, primStream* pStream){ Int i; directedLine *temp, *oldtemp = NULL; Int tempIndex, oldtempIndex = 0; assert(inc_chain != NULL && dec_chain != NULL); if(inc_chain == botVertex) { reflexChain rChain(20, 0); rChain.processNewVertex(topVertex->getVertex(top_index), pStream); for(i=dec_index; i< dec_chain->get_npoints(); i++){ rChain.processNewVertex(dec_chain->getVertex(i), pStream); } for(temp = dec_chain->getPrev(); temp != botVertex; temp = temp->getPrev()) { for(i=0; i<temp->get_npoints(); i++){ rChain.processNewVertex(temp->getVertex(i), pStream); } } } else if(dec_chain==botVertex) { reflexChain rChain(20, 1); rChain.processNewVertex(topVertex->getVertex(top_index), pStream); for(i=inc_index; i< inc_chain->get_npoints(); i++){ rChain.processNewVertex(inc_chain->getVertex(i), pStream); } for(temp = inc_chain->getPrev(); temp != botVertex; temp = temp->getNext()) { for(i=0; i<temp->get_npoints(); i++){ rChain.processNewVertex(temp->getVertex(i), pStream); } } } else /*neither reached the bottom*/{ if(compV2InY(inc_chain->getVertex(inc_index), dec_chain->getVertex(dec_index)) <=0) { reflexChain rChain(20, 0); rChain.processNewVertex(topVertex -> getVertex(top_index), pStream); temp = dec_chain; tempIndex = dec_index; while( compV2InY(inc_chain->getVertex(inc_index), temp->getVertex(tempIndex))<=0) { oldtemp = temp; oldtempIndex = tempIndex; rChain.processNewVertex(temp->getVertex(tempIndex), pStream); if(tempIndex == temp->get_npoints()-1){ tempIndex = 0; temp = temp->getPrev(); } else{ tempIndex++; } } rChain.outputFan(inc_chain->getVertex(inc_index), pStream); monoTriangulationRec(inc_chain, inc_index, temp, tempIndex, oldtemp, oldtempIndex, botVertex, pStream); } else /* >0*/ { reflexChain rChain(20, 1); rChain.processNewVertex(topVertex -> getVertex(top_index), pStream); temp = inc_chain; tempIndex = inc_index; while( compV2InY(temp->getVertex(tempIndex), dec_chain->getVertex(dec_index))>0){ oldtemp = temp; oldtempIndex = tempIndex; rChain.processNewVertex(temp->getVertex(tempIndex), pStream); if(tempIndex == temp->get_npoints()-1){ tempIndex = 0; temp = temp->getNext(); } else{ tempIndex++; } } rChain.outputFan(dec_chain->getVertex(dec_index), pStream); monoTriangulationRec(temp, tempIndex, dec_chain, dec_index, oldtemp, oldtempIndex, botVertex, pStream); } } /*end case neither reached the bottom*/}/***************************vertexArray begin here**********************************/vertexArray::vertexArray(Real2* vertices, Int nVertices){ Int i; size = index = nVertices; array = (Real**) malloc(sizeof(Real*) * nVertices); assert(array); for(i=0; i<nVertices; i++) { array[i] = vertices[i]; array[i] = vertices[i]; }}vertexArray::vertexArray(Int s){ size = s; array = (Real**) malloc(sizeof(Real*) * s); assert(array); index = 0;}vertexArray::~vertexArray(){ free(array);}void vertexArray::appendVertex(Real* ptr){ Int i; if(index >= size){ Real** temp = (Real**) malloc(sizeof(Real*) * (2*size +1)); assert(temp); for(i=0; i<index; i++) temp[i] = array[i]; free(array); array = temp; size = 2*size+1; } array[index++] = ptr;}void vertexArray::print(){ printf("vertex Array:index=%i, size=%i\n", index, size); for(Int i=0; i<index; i++) { printf("(%f,%f) ", array[i][0], array[i][1]); } printf("\n");}/*find the first i such that array[i][1] >= v * and array[i+1][1] <v * if index == 0 (the array is empty, return -1. * if v is above all, return -1. * if v is below all, return index-1. */Int vertexArray::findIndexAbove(Real v){ Int i; if(index == 0) return -1; else if(array[0][1] < v) return -1; else { for(i=1; i<index; i++) { if(array[i][1] < v) break; } return i-1; }}/*find the first i<=endIndex such that array[i][1] <= v * and array[i-1][1] > v *if sartIndex>endIndex, then return endIndex+1. *otherwise, startIndex<=endIndex, it is assumed that * 0<=startIndex<=endIndex<index. * if v is below all, return endIndex+1 * if v is above all, return startIndex. */Int vertexArray::findIndexBelowGen(Real v, Int startIndex, Int endIndex){ Int i; if(startIndex > endIndex) return endIndex+1; else if(array[endIndex][1] > v) return endIndex+1; else //now array[endIndex][1] <= v { for(i=endIndex-1; i>=startIndex; i--) { if(array[i][1] > v) break; } return i+1; }}/*find the first i<=endIndex such that array[i-1][1] >= v * and array[i][1] < v *if sartIndex>endIndex, then return endIndex+1. *otherwise, startIndex<=endIndex, it is assumed that * 0<=startIndex<=endIndex<index. * if v is below or equal to all, return endIndex+1 * if v is strictly above all, return startIndex. */Int vertexArray::findIndexStrictBelowGen(Real v, Int startIndex, Int endIndex){ Int i; if(startIndex > endIndex) return endIndex+1; else if(array[endIndex][1] >= v) return endIndex+1; else //now array[endIndex][1] < v { for(i=endIndex-1; i>=startIndex; i--) { if(array[i][1] >= v) break; } return i+1; }}/*find the first i>startIndex such that array[i-1][1] > v * and array[i][1] >=v *if sartIndex>endIndex, then return startIndex-1. *otherwise, startIndex<=endIndex, it is assumed that * 0<=startIndex<=endIndex<index. * if v is strictly above all, return startIndex-1 * if v is strictly below all, return endIndex. */Int vertexArray::findIndexFirstAboveEqualGen(Real v, Int startIndex, Int endIndex){ Int i; if(startIndex > endIndex) return startIndex-1; else if(array[startIndex][1] < v) return startIndex-1; else //now array[startIndex][1] >= v { for(i=startIndex; i<=endIndex; i++) { if(array[i][1] <= v) break; } if(i>endIndex) // v is strictly below all return endIndex; else if(array[i][1] == v) return i; else return i-1; }}/*find the first i>=startIndex such that array[i][1] >= v * and array[i+1][1] <v *if sartIndex>endIndex, then return startIndex-1. *otherwise, startIndex<=endIndex, it is assumed that * 0<=startIndex<=endIndex<index. * if v is above all, return startIndex-1 * if v is below all, return endIndex. */Int vertexArray::findIndexAboveGen(Real v, Int startIndex, Int endIndex){ Int i; if(startIndex > endIndex) return startIndex-1; else if(array[startIndex][1] < v) return startIndex-1; else //now array[startIndex][1] >= v { for(i=startIndex+1; i<=endIndex; i++) { if(array[i][1] < v) break; } return i-1; }}Int vertexArray::findDecreaseChainFromEnd(Int begin, Int end){ Int i = end; Real prevU = array[i][0]; Real thisU; for(i=end-1; i>=begin; i--){ thisU = array[i][0]; if(thisU < prevU) prevU = thisU; else break; } return i;}//if(V(start) == v, return start, other wise return the//last i so that V(i)==vInt vertexArray::skipEqualityFromStart(Real v, Int start, Int end){ Int i; if(array[start][1] != v) return start; //now array[start][1] == v for(i=start+1; i<= end; i++) if(array[i][1] != v) break; return i-1;} /***************************vertexArray end****************************************//***************************relfex chain stuff begin here*****************************/reflexChain::reflexChain(Int size, Int is_increasing){ queue = (Real2*) malloc(sizeof(Real2) * size); assert(queue); index_queue = 0; size_queue = size; isIncreasing = is_increasing;}reflexChain::~reflexChain(){ free(queue);}/*put (u,v) at the end of the queue *pay attention to space */void reflexChain::insert(Real u, Real v){ Int i; if(index_queue >= size_queue) { Real2 *temp = (Real2*) malloc(sizeof(Real2) * (2*size_queue+1)); assert(temp); /*copy*/ for(i=0; i<index_queue; i++){ temp[i][0] = queue[i][0]; temp[i][1] = queue[i][1]; } free(queue); queue = temp; size_queue = 2*size_queue + 1; } queue[index_queue][0] = u; queue[index_queue][1] = v; index_queue ++;}void reflexChain::insert(Real v[2]){ insert(v[0], v[1]);}/*static Real area(Real A[2], Real B[2], Real C[2]){ Real Bx, By, Cx, Cy; Bx = B[0] - A[0]; By = B[1] - A[1]; Cx = C[0] - A[0]; Cy = C[1] - A[1]; return Bx*Cy - Cx*By;}*//*the chain is reflex, and the vertex v is *on the other side of the chain, so that *we can outout the fan with v as the *the center */void reflexChain::outputFan(Real v[2], primStream* pStream){ Int i; pStream->begin(); pStream->insert(v); if(isIncreasing) { for(i=0; i<index_queue; i++) pStream->insert(queue[i]); } else { for(i=index_queue-1; i>=0; i--) pStream->insert(queue[i]); } pStream->end(PRIMITIVE_STREAM_FAN);}void reflexChain::processNewVertex(Real v[2], primStream* pStream){ Int i,j,k; Int isReflex; /*if there are at most one vertex in the queue, then simply insert */ if(index_queue <=1){ insert(v); return; } /*there are at least two vertices in the queue*/ j=index_queue-1; for(i=j; i>=1; i--) { if(isIncreasing) { isReflex = (area(queue[i-1], queue[i], v) <= 0.0); } else /*decreasing*/{ isReflex = (area(v, queue[i], queue[i-1]) <= 0.0); } if(isReflex) { break; } } /* *if i<j then vertices: i+1--j are convex * output triangle fan: * v, and queue[i], i+1, ..., j */ if(i<j) { pStream->begin(); pStream->insert(v); if(isIncreasing) { for(k=i; k<=j; k++) pStream->insert(queue[k]); } else { for(k=j; k>=i; k--) pStream->insert(queue[k]); } pStream->end(PRIMITIVE_STREAM_FAN); } /*delete vertices i+1--j from the queue*/ index_queue = i+1; /*finally insert v at the end of the queue*/ insert(v);}void reflexChain::print(){ Int i; printf("reflex chain: isIncreasing=%i\n", isIncreasing); for(i=0; i<index_queue; i++) { printf("(%f,%f) ", queue[i][0], queue[i][1]); } printf("\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -