📄 samplemonopoly.cc
字号:
}
#ifdef MYDEBUG
printf("***********leave findUpCorners\n");
#endif
}
//return 1 if neck exists, 0 othewise
Int findNeckF(vertexArray *leftChain, Int botLeftIndex,
vertexArray *rightChain, Int botRightIndex,
gridBoundaryChain* leftGridChain,
gridBoundaryChain* rightGridChain,
Int gridStartIndex,
Int& neckLeft,
Int& neckRight)
{
/*
printf("enter findNeckF, botleft, botright=%i,%i,gstartindex=%i\n",botLeftIndex,botRightIndex,gridStartIndex);
printf("leftChain is\n");
leftChain->print();
printf("rightChain is\n");
rightChain->print();
*/
Int lowerGridIndex; //the grid below leftChain and rightChian vertices
Int i;
Int n_vlines = leftGridChain->get_nVlines();
Real v;
if(botLeftIndex >= leftChain->getNumElements() ||
botRightIndex >= rightChain->getNumElements())
return 0; //no neck exists
v=min(leftChain->getVertex(botLeftIndex)[1], rightChain->getVertex(botRightIndex)[1]);
for(i=gridStartIndex; i<n_vlines; i++)
if(leftGridChain->get_v_value(i) <= v &&
leftGridChain->getUlineIndex(i)<= rightGridChain->getUlineIndex(i))
break;
lowerGridIndex = i;
if(lowerGridIndex == n_vlines) //the two trm vertex are higher than all gridlines
return 0;
else
{
Int botLeft2, botRight2;
/*
printf("leftGridChain->get_v_)value=%f\n",leftGridChain->get_v_value(lowerGridIndex), botLeftIndex);
printf("leftChain->get_vertex(0)=(%f,%f)\n", leftChain->getVertex(0)[0],leftChain->getVertex(0)[1]);
printf("leftChain->get_vertex(1)=(%f,%f)\n", leftChain->getVertex(1)[0],leftChain->getVertex(1)[1]);
printf("leftChain->get_vertex(2)=(%f,%f)\n", leftChain->getVertex(2)[0],leftChain->getVertex(2)[1]);
*/
botLeft2 = leftChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botLeftIndex, leftChain->getNumElements()-1) -1 ;
/*
printf("botLeft2=%i\n", botLeft2);
printf("leftChain->getNumElements=%i\n", leftChain->getNumElements());
*/
botRight2 = rightChain->findIndexFirstAboveEqualGen(leftGridChain->get_v_value(lowerGridIndex), botRightIndex, rightChain->getNumElements()-1) -1;
if(botRight2 < botRightIndex) botRight2=botRightIndex;
if(botLeft2 < botLeftIndex) botLeft2 = botLeftIndex;
assert(botLeft2 >= botLeftIndex);
assert(botRight2 >= botRightIndex);
//find nectLeft so that it is th erightmost vertex on letChain
Int tempI = botLeftIndex;
Real temp = leftChain->getVertex(tempI)[0];
for(i=botLeftIndex+1; i<= botLeft2; i++)
if(leftChain->getVertex(i)[0] > temp)
{
temp = leftChain->getVertex(i)[0];
tempI = i;
}
neckLeft = tempI;
tempI = botRightIndex;
temp = rightChain->getVertex(tempI)[0];
for(i=botRightIndex+1; i<= botRight2; i++)
if(rightChain->getVertex(i)[0] < temp)
{
temp = rightChain->getVertex(i)[0];
tempI = i;
}
neckRight = tempI;
return 1;
}
}
/*find i>=botLeftIndex,j>=botRightIndex so that
*(leftChain[i], rightChain[j]) is a neck.
*/
void findNeck(vertexArray *leftChain, Int botLeftIndex,
vertexArray *rightChain, Int botRightIndex,
Int& leftLastIndex, /*left point of the neck*/
Int& rightLastIndex /*right point of the neck*/
)
{
assert(botLeftIndex < leftChain->getNumElements() &&
botRightIndex < rightChain->getNumElements());
/*now the neck exists for sure*/
if(leftChain->getVertex(botLeftIndex)[1] <= rightChain->getVertex(botRightIndex)[1]) //left below right
{
leftLastIndex = botLeftIndex;
/*find i so that rightChain[i][1] >= leftchainbotverte[1], and i+1<
*/
rightLastIndex=rightChain->findIndexAboveGen(leftChain->getVertex(botLeftIndex)[1], botRightIndex+1, rightChain->getNumElements()-1);
}
else //left above right
{
rightLastIndex = botRightIndex;
leftLastIndex = leftChain->findIndexAboveGen(rightChain->getVertex(botRightIndex)[1],
botLeftIndex+1,
leftChain->getNumElements()-1);
}
}
void findLeftGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices)
{
Int i,k,isHoriz = 0;
Int n_ulines = grid->get_n_ulines();
Real uMin = grid->get_u_min();
Real uMax = grid->get_u_max();
Real slop = 0.0f, uinterc;
#ifdef SHORTEN_GRID_LINE
//uintercBuf stores all the interction u value for each grid line
//notice that lastGridIndex<= firstGridIndex
Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
assert(uintercBuf);
#endif
/*initialization to make vtail bigger than grid->...*/
directedLine* dLine = topEdge;
Real vtail = grid->get_v_value(firstGridIndex) + 1.0;
Real tempMaxU = grid->get_u_min();
/*for each grid line*/
for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
{
Real grid_v_value = grid->get_v_value(i);
/*check whether this grid line is below the current trim edge.*/
if(vtail > grid_v_value)
{
/*since the grid line is below the trim edge, we
*find the trim edge which will contain the trim line
*/
while( (vtail=dLine->tail()[1]) > grid_v_value){
tempMaxU = max(tempMaxU, dLine->tail()[0]);
dLine = dLine -> getNext();
}
if( fabs(dLine->head()[1] - vtail) < ZERO)
isHoriz = 1;
else
{
isHoriz = 0;
slop = (dLine->head()[0] - dLine->tail()[0]) / (dLine->head()[1]-vtail);
}
}
if(isHoriz)
{
uinterc = max(dLine->head()[0], dLine->tail()[0]);
}
else
{
uinterc = slop * (grid_v_value - vtail) + dLine->tail()[0];
}
tempMaxU = max(tempMaxU, uinterc);
if(uinterc < uMin && uinterc >= uMin - ZERO)
uinterc = uMin;
if(uinterc > uMax && uinterc <= uMax + ZERO)
uinterc = uMax;
#ifdef SHORTEN_GRID_LINE
uintercBuf[k] = uinterc;
#endif
assert(uinterc >= uMin && uinterc <= uMax);
if(uinterc == uMax)
ret_indices[k] = n_ulines-1;
else
ret_indices[k] = (Int)(((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
if(ret_indices[k] >= n_ulines)
ret_indices[k] = n_ulines-1;
ret_innerIndices[k] = (Int)(((tempMaxU-uMin)/(uMax - uMin)) * (n_ulines-1)) + 1;
/*reinitialize tempMaxU for next grdiLine*/
tempMaxU = uinterc;
}
#ifdef SHORTEN_GRID_LINE
//for each grid line, compare the left grid point with the
//intersection point. If the two points are too close, then
//we should move the grid point one grid to the right
//and accordingly we should update the inner index.
for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
{
//check gridLine i
//check ret_indices[k]
Real a = grid->get_u_value(ret_indices[k]-1);
Real b = grid->get_u_value(ret_indices[k]);
assert(uintercBuf[k] >= a && uintercBuf < b);
if( (b-uintercBuf[k]) <= 0.2 * (b-a)) //interc is very close to b
{
ret_indices[k]++;
}
//check ret_innerIndices[k]
if(k>0)
{
if(ret_innerIndices[k] < ret_indices[k-1])
ret_innerIndices[k] = ret_indices[k-1];
if(ret_innerIndices[k] < ret_indices[k])
ret_innerIndices[k] = ret_indices[k];
}
}
//clean up
free(uintercBuf);
#endif
}
void findRightGridIndices(directedLine* topEdge, Int firstGridIndex, Int lastGridIndex, gridWrap* grid, Int* ret_indices, Int* ret_innerIndices)
{
Int i,k;
Int n_ulines = grid->get_n_ulines();
Real uMin = grid->get_u_min();
Real uMax = grid->get_u_max();
Real slop = 0.0f, uinterc;
#ifdef SHORTEN_GRID_LINE
//uintercBuf stores all the interction u value for each grid line
//notice that firstGridIndex >= lastGridIndex
Real *uintercBuf = (Real *) malloc (sizeof(Real) * (firstGridIndex-lastGridIndex+1));
assert(uintercBuf);
#endif
/*initialization to make vhead bigger than grid->v_value...*/
directedLine* dLine = topEdge->getPrev();
Real vhead = dLine->tail()[1];
Real tempMinU = grid->get_u_max();
/*for each grid line*/
for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
{
Real grid_v_value = grid->get_v_value(i);
/*check whether this grid line is below the current trim edge.*/
if(vhead >= grid_v_value)
{
/*since the grid line is below the tail of the trim edge, we
*find the trim edge which will contain the trim line
*/
while( (vhead=dLine->head()[1]) > grid_v_value){
tempMinU = min(tempMinU, dLine->head()[0]);
dLine = dLine -> getPrev();
}
/*skip the equality in the case of degenerat case: horizontal */
while(dLine->head()[1] == grid_v_value)
dLine = dLine->getPrev();
assert( dLine->tail()[1] != dLine->head()[1]);
slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-dLine->head()[1]);
/*
if(dLine->tail()[1] == vhead)
isHoriz = 1;
else
{
isHoriz = 0;
slop = (dLine->tail()[0] - dLine->head()[0]) / (dLine->tail()[1]-vhead);
}
*/
}
uinterc = slop * (grid_v_value - dLine->head()[1]) + dLine->head()[0];
//in case unterc is outside of the grid due to floating point
if(uinterc < uMin)
uinterc = uMin;
else if(uinterc > uMax)
uinterc = uMax;
#ifdef SHORTEN_GRID_LINE
uintercBuf[k] = uinterc;
#endif
tempMinU = min(tempMinU, uinterc);
assert(uinterc >= uMin && uinterc <= uMax);
if(uinterc == uMin)
ret_indices[k] = 0;
else
ret_indices[k] = (int)ceil((((uinterc-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
/*
if(ret_indices[k] >= grid->get_n_ulines())
{
printf("ERROR3\n");
exit(0);
}
if(ret_indices[k] < 0)
{
printf("ERROR4\n");
exit(0);
}
*/
ret_innerIndices[k] = (int)ceil ((((tempMinU-uMin)/(uMax - uMin)) * (n_ulines-1))) -1;
tempMinU = uinterc;
}
#ifdef SHORTEN_GRID_LINE
//for each grid line, compare the left grid point with the
//intersection point. If the two points are too close, then
//we should move the grid point one grid to the right
//and accordingly we should update the inner index.
for(k=0, i=firstGridIndex; i>=lastGridIndex; i--, k++)
{
//check gridLine i
//check ret_indices[k]
Real a = grid->get_u_value(ret_indices[k]);
Real b = grid->get_u_value(ret_indices[k]+1);
assert(uintercBuf[k] > a && uintercBuf <= b);
if( (uintercBuf[k]-a) <= 0.2 * (b-a)) //interc is very close to a
{
ret_indices[k]--;
}
//check ret_innerIndices[k]
if(k>0)
{
if(ret_innerIndices[k] > ret_indices[k-1])
ret_innerIndices[k] = ret_indices[k-1];
if(ret_innerIndices[k] > ret_indices[k])
ret_innerIndices[k] = ret_indices[k];
}
}
//clean up
free(uintercBuf);
#endif
}
void sampleMonoPoly(directedLine* polygon, gridWrap* grid, Int ulinear, Int vlinear, primStream* pStream, rectBlockArray* rbArray)
{
/*
{
grid->print();
polygon->writeAllPolygons("zloutputFile");
exit(0);
}
*/
if(grid->get_n_ulines() == 2 ||
grid->get_n_vlines() == 2)
{
if(ulinear && grid->get_n_ulines() == 2)
{
monoTriangulationFun(polygon, compV2InY, pStream);
return;
}
else if(DBG_isConvex(polygon) && polygon->numEdges() >=4)
{
triangulateConvexPoly(polygon, ulinear, vlinear, pStream);
return;
}
else if(vlinear || DBG_is_U_direction(polygon))
{
Int n_cusps;//num interior cusps
Int n_edges = polygon->numEdges();
directedLine** cusps = (directedLine**) malloc(sizeof(directedLine*) * n_edges);
assert(cusps);
findInteriorCuspsX(polygon, n_cusps, cusps);
if(n_cusps == 0) //u_monotone
{
monoTriangulationFun(polygon, compV2InX, pStream);
free(cusps);
return;
}
else if(n_cusps == 1) //one interior cusp
{
directedLine* new_polygon = polygonConvert(cusps[0]);
directedLine* other = findDiagonal_singleCuspX( new_polygon);
//<other> should NOT be null unless there are self-intersecting
//trim curves. In that case, we don't want to core dump, instead,
//we triangulate anyway, and print out error message.
if(other == NULL)
{
monoTriangulationFun(polygon, compV2InX, pStream);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -