int main(int argc,char **argv) { PetscErrorCode ierr; PetscInt degrees[1000],ndegrees,npoints,two; PetscReal points[1000],weights[1000],interval[2]; PetscBool flg; ierr = PetscInitialize(&argc,&argv,(char*)0,help);CHKERRQ(ierr); ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"Discretization tools test options",NULL);CHKERRQ(ierr); { ndegrees = 1000; degrees[0] = 0; degrees[1] = 1; degrees[2] = 2; ierr = PetscOptionsIntArray("-degrees","list of degrees to evaluate","",degrees,&ndegrees,&flg);CHKERRQ(ierr); if (!flg) ndegrees = 3; npoints = 1000; points[0] = 0.0; points[1] = -0.5; points[2] = 1.0; ierr = PetscOptionsRealArray("-points","list of points at which to evaluate","",points,&npoints,&flg);CHKERRQ(ierr); if (!flg) npoints = 3; two = 2; interval[0] = -1.; interval[1] = 1.; ierr = PetscOptionsRealArray("-interval","interval on which to construct quadrature","",interval,&two,NULL);CHKERRQ(ierr); } ierr = PetscOptionsEnd();CHKERRQ(ierr); ierr = CheckPoints("User-provided points",npoints,points,ndegrees,degrees);CHKERRQ(ierr); ierr = PetscDTGaussQuadrature(npoints,interval[0],interval[1],points,weights);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Quadrature weights\n");CHKERRQ(ierr); ierr = PetscRealView(npoints,weights,PETSC_VIEWER_STDOUT_WORLD);CHKERRQ(ierr); { PetscReal a = interval[0],b = interval[1],zeroth,first,second; PetscInt i; zeroth = b - a; first = (b*b - a*a)/2; second = (b*b*b - a*a*a)/3; for (i=0; i<npoints; i++) { zeroth -= weights[i]; first -= weights[i] * points[i]; second -= weights[i] * PetscSqr(points[i]); } if (PetscAbs(zeroth) < 1e-10) zeroth = 0.; if (PetscAbs(first) < 1e-10) first = 0.; if (PetscAbs(second) < 1e-10) second = 0.; ierr = PetscPrintf(PETSC_COMM_WORLD,"Moment error: zeroth=%g, first=%g, second=%g\n",(double)(-zeroth),(double)(-first),(double)(-second));CHKERRQ(ierr); } ierr = CheckPoints("Gauss points",npoints,points,ndegrees,degrees);CHKERRQ(ierr); ierr = PetscFinalize(); return 0; }
static void AddEdgeToRing( OGRLinearRing * poRing, OGRLineString * poLine, int bReverse ) { /* -------------------------------------------------------------------- */ /* Establish order and range of traverse. */ /* -------------------------------------------------------------------- */ int iStart=0, iEnd=0, iStep=0; int nVertToAdd = poLine->getNumPoints(); if( !bReverse ) { iStart = 0; iEnd = nVertToAdd - 1; iStep = 1; } else { iStart = nVertToAdd - 1; iEnd = 0; iStep = -1; } /* -------------------------------------------------------------------- */ /* Should we skip a repeating vertex? */ /* -------------------------------------------------------------------- */ if( poRing->getNumPoints() > 0 && CheckPoints( poRing, poRing->getNumPoints()-1, poLine, iStart, NULL ) ) { iStart += iStep; } /* -------------------------------------------------------------------- */ /* Append points to ring. */ /* -------------------------------------------------------------------- */ int iOutVertex = poRing->getNumPoints(); poRing->setNumPoints( iOutVertex + ABS(iEnd-iStart) + 1 ); for( int i = iStart; i != (iEnd+iStep); i += iStep ) { poRing->setPoint( iOutVertex++, poLine->getX(i), poLine->getY(i), poLine->getZ(i) ); } }
OGRGeometryH OGRBuildPolygonFromEdges( OGRGeometryH hLines, int bBestEffort, int bAutoClose, double dfTolerance, OGRErr * peErr ) { int bSuccess = TRUE; OGRGeometryCollection *poLines = (OGRGeometryCollection *) hLines; OGRPolygon *poPolygon = new OGRPolygon(); (void) bBestEffort; /* -------------------------------------------------------------------- */ /* Setup array of line markers indicating if they have been */ /* added to a ring yet. */ /* -------------------------------------------------------------------- */ int nEdges = poLines->getNumGeometries(); int *panEdgeConsumed, nRemainingEdges = nEdges; panEdgeConsumed = (int *) CPLCalloc(sizeof(int),nEdges); /* ==================================================================== */ /* Loop generating rings. */ /* ==================================================================== */ while( nRemainingEdges > 0 ) { int iEdge; OGRLineString *poLine; /* -------------------------------------------------------------------- */ /* Find the first unconsumed edge. */ /* -------------------------------------------------------------------- */ for( iEdge = 0; panEdgeConsumed[iEdge]; iEdge++ ) {} poLine = (OGRLineString *) poLines->getGeometryRef(iEdge); /* -------------------------------------------------------------------- */ /* Start a new ring, copying in the current line directly */ /* -------------------------------------------------------------------- */ OGRLinearRing *poRing = new OGRLinearRing(); AddEdgeToRing( poRing, poLine, FALSE ); panEdgeConsumed[iEdge] = TRUE; nRemainingEdges--; /* ==================================================================== */ /* Loop adding edges to this ring until we make a whole pass */ /* within finding anything to add. */ /* ==================================================================== */ int bWorkDone = TRUE; double dfBestDist = dfTolerance; while( !CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1,NULL) && nRemainingEdges > 0 && bWorkDone ) { int iBestEdge = -1, bReverse = FALSE; bWorkDone = FALSE; dfBestDist = dfTolerance; // We consider linking the end to the beginning. If this is // closer than any other option we will just close the loop. //CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1,&dfBestDist); // Find unused edge with end point closest to our loose end. for( iEdge = 0; iEdge < nEdges; iEdge++ ) { if( panEdgeConsumed[iEdge] ) continue; poLine = (OGRLineString *) poLines->getGeometryRef(iEdge); if( CheckPoints(poLine,0,poRing,poRing->getNumPoints()-1, &dfBestDist) ) { iBestEdge = iEdge; bReverse = FALSE; } if( CheckPoints(poLine,poLine->getNumPoints()-1, poRing,poRing->getNumPoints()-1, &dfBestDist) ) { iBestEdge = iEdge; bReverse = TRUE; } } // We found one within tolerance - add it. if( iBestEdge != -1 ) { poLine = (OGRLineString *) poLines->getGeometryRef(iBestEdge); AddEdgeToRing( poRing, poLine, bReverse ); panEdgeConsumed[iBestEdge] = TRUE; nRemainingEdges--; bWorkDone = TRUE; } } /* -------------------------------------------------------------------- */ /* Did we fail to complete the ring? */ /* -------------------------------------------------------------------- */ dfBestDist = dfTolerance; if( !CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1, &dfBestDist) ) { CPLDebug( "OGR", "Failed to close ring %d.\n" "End Points are: (%.8f,%.7f) and (%.7f,%.7f)\n", poPolygon->getNumInteriorRings()+1, poRing->getX(0), poRing->getY(0), poRing->getX(poRing->getNumPoints()-1), poRing->getY(poRing->getNumPoints()-1) ); bSuccess = FALSE; } /* -------------------------------------------------------------------- */ /* Do we need to auto-close this ring? */ /* -------------------------------------------------------------------- */ if( bAutoClose && !CheckPoints(poRing,0,poRing,poRing->getNumPoints()-1,NULL) ) { poRing->addPoint( poRing->getX(0), poRing->getY(0), poRing->getZ(0)); } poPolygon->addRingDirectly( poRing ); } /* next ring */ /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ CPLFree( panEdgeConsumed ); // Eventually we should at least identify the external ring properly, // perhaps even ordering the direction of rings, though this isn't // required by the OGC geometry model. if( peErr != NULL ) { if( bSuccess ) *peErr = OGRERR_NONE; else *peErr = OGRERR_FAILURE; } return (OGRGeometryH) poPolygon; }