void GeomShape::opSub( GeomShape *otherShape ) { // Use the GPC library // @TODO: Assert that all polys in this and other are at z==0 because // the gpc system supports only 2D // MAKE the gpc "polygon" structs which are roughly equivilent to our "GeomShape" // CONVERT our shape to GPC's "polygon" gpc_polygon *gpcA = geomShapeToGpcPolygon( this ); gpc_polygon *gpcB = geomShapeToGpcPolygon( otherShape ); gpc_polygon gpcC; gpc_polygon_clip( GPC_DIFF, gpcA, gpcB, &gpcC ); // CONVERT GPC's "polygon" to our shape GeomShape *resultShape = gpcPolygonToGeomShape( &gpcC ); copy( resultShape ); // *this = *resultShape; // @TODO: Step into this above line and see if it does the same thing as copy constructor gpc_free_polygon( gpcA ); gpc_free_polygon( gpcB ); gpc_free_polygon( &gpcC ); }
// start inclusive, end exclusive gpc_polygon *gpc_read_all_polygon_recursive(int start, int end) { int split; gpc_polygon *first; gpc_polygon * second; gpc_polygon * merged; MALLOC(merged, sizeof(gpc_polygon), "allocating accumulated gpc", gpc_polygon); if (end - start == 2) { first = gpc_read_leaf_gen(); second = gpc_read_leaf_gen(); gpc_polygon_clip(GPC_UNION, first, second, merged); gpc_free_polygon(first); gpc_free_polygon(second); FREE(first); FREE(second); return merged; } else if (end - start == 1){ return gpc_read_leaf_gen(); } else { split = (start + end) / 2; first = gpc_read_all_polygon_recursive(start, split); second = gpc_read_all_polygon_recursive(split, end); gpc_polygon_clip(GPC_UNION, first, second, merged); gpc_free_polygon(first); gpc_free_polygon(second); FREE(first); FREE(second); return merged; } }
void gpc_write_polygon_MATLAB(mxArray *plhs, gpc_polygon *p) { int c, v; int dims[2]; mxArray *field_x, *field_y, *field_hole; const char *field_names[] = {"x","y","hole"}; dims[0]=1; dims[1]=p->num_contours; for (c=0; c < p->num_contours; c++) { field_x = mxCreateDoubleMatrix(p->contour[c].num_vertices,1,mxREAL); field_y = mxCreateDoubleMatrix(p->contour[c].num_vertices,1,mxREAL); for (v= 0; v < p->contour[c].num_vertices; v++) { ((double*)mxGetPr(field_x))[v]=p->contour[c].vertex[v].x; ((double*)mxGetPr(field_y))[v]=p->contour[c].vertex[v].y; } mxSetFieldByNumber(plhs,c,0,field_x); mxSetFieldByNumber(plhs,c,1,field_y); field_hole = mxCreateDoubleMatrix(1,1,mxREAL); ((double*)mxGetPr(field_hole))[0]=p->hole[c]; mxSetFieldByNumber(plhs,c,2,field_hole); } gpc_free_polygon(p); }
void CPolyLine::ClipGpcPolygon( gpc_op op, CPolyLine * clip_poly ) { gpc_polygon * result = new gpc_polygon; gpc_polygon_clip( op, m_gpc_poly, clip_poly->GetGpcPoly(), result ); gpc_free_polygon( m_gpc_poly ); delete m_gpc_poly; m_gpc_poly = result; }
static const paths& clip(const Paths& paths, unsigned int count, const path& edge, ClipType clip_type) { gpc_vertex_list gvl = {1, memory::malloc<gpc_vertex>()}; gpc_polygon subject = {0, nullptr, nullptr}; gpc_polygon clip = {0, nullptr, nullptr}; gpc_polygon result = {0, nullptr, nullptr}; for (unsigned int i = 0; i < count; ++i) gpc_add_contour(&subject, &gpc::fill(gvl, paths[i]), 0); gpc_add_contour(&clip, &gpc::fill(gvl, edge), 0); gpc_op op; switch (clip_type) { default: case ctInt: op = GPC_INT; break; case ctDiff: op = GPC_DIFF; break; case ctXor: op = GPC_XOR; break; case ctUnion: op = GPC_UNION; break; } gpc_polygon_clip(op, &subject, &clip, &result); static class paths clipped_paths; clipped_paths.clear(); for (int i = 0; i < result.num_contours; ++i) { vertex_set* clipped_result = new vertex_set; const gpc_vertex_list& gvl = result.contour[i]; for (int i = 0; i < gvl.num_vertices; ++i) clipped_result->append(gvl.vertex[i].x, gvl.vertex[i].y); clipped_paths.append(clipped_result); } gpc_free_polygon(&result); gpc_free_polygon(&clip); gpc_free_polygon(&subject); memory::free(gvl.vertex, gvl.num_vertices); return clipped_paths; }
SEXP Rgpc_polygon_clip(SEXP subjpoly, SEXP clippoly, SEXP op) { gpc_polygon subject, clip, result; int polysize, nsubj, nclip, iop; SEXP returnval; double *xreturnval; double *xsubjpoly, *xclippoly, *xop; PROTECT(subjpoly = AS_NUMERIC(subjpoly)); PROTECT(clippoly = AS_NUMERIC(clippoly)); PROTECT(op = AS_NUMERIC(op)); nsubj = LENGTH(subjpoly); nclip = LENGTH(clippoly); xsubjpoly = NUMERIC_POINTER(subjpoly); xclippoly = NUMERIC_POINTER(clippoly); xop = NUMERIC_POINTER(op); iop = (int) *xop; double_to_gpc_polygon(&subject, xsubjpoly, nsubj); double_to_gpc_polygon(&clip, xclippoly, nclip); if(iop == 1) gpc_polygon_clip(GPC_INT, &subject, &clip, &result); else if(iop == 2) gpc_polygon_clip(GPC_DIFF, &subject, &clip, &result); else gpc_polygon_clip(GPC_UNION, &subject, &clip, &result); polysize = compute_polygon_size(&result); PROTECT(returnval = NEW_NUMERIC(polysize)); xreturnval = NUMERIC_POINTER(returnval); gpc_polygon_to_double(xreturnval, polysize, &result); gpc_free_polygon(&subject); gpc_free_polygon(&clip); gpc_free_polygon(&result); UNPROTECT(4); return(returnval); }
static void free_polygon_as_GDestroyNotify (gpointer data) { gpc_polygon *poly; poly = (gpc_polygon *)data; gpc_free_polygon (poly); g_free (poly); return; }
// close currently opened level, free memory, reset vars void GameDataEndLevel() { gpc_free_polygon(&oPolyLevel); #ifdef EX0_CLIENT gpc_free_tristrip(&oTristripLevel); // DEBUG: Close the PolyBoolean level PAREA::Del(&pPolyBooleanLevel); #endif // EX0_CLIENT }
int main() { gpc_polygon subject, clip, result; FILE *sfp, *cfp, *ofp; printf("2\n"); sfp= fopen("TEST_tree.gpf", "r"); cfp= fopen("TEST_kachel.gpf", "r"); //sfp= fopen("/home/heiner/flo/gpct101/polygons/britain.gpf", "r"); //cfp= fopen("/home/heiner/flo/gpct101/polygons/arrows.gpf", "r"); printf("3\n"); gpc_read_polygon(sfp, 0, &subject); printf("1\n"); gpc_read_polygon(cfp, 0, &clip); printf("4\n"); gpc_polygon_clip(GPC_INT, &subject, &clip, &result); printf("5\n"); ofp= fopen("ERGEBNIS", "w"); gpc_write_polygon(ofp, 0, &result); printf("6\n"); gpc_free_polygon(&subject); gpc_free_polygon(&clip); gpc_free_polygon(&result); printf("7\n"); fclose(sfp); fclose(cfp); fclose(ofp); return 0; }
cElPolygone cElPolygone::GenOp(const cElPolygone & aPol,INT anOp)const { gpc_polygon aGpcPol1 = ToGPC(); gpc_polygon aGpcPol2 = aPol.ToGPC(); gpc_polygon aGpcRes; gpc_polygon_clip (gpc_op(anOp),&aGpcPol1,&aGpcPol2,&aGpcRes); cElPolygone aRes(aGpcRes); GpcEl_Free(aGpcPol1); GpcEl_Free(aGpcPol2); gpc_free_polygon(&aGpcRes); return aRes; }
static PyObject *Polygon_simplify(Polygon *self, PyObject *args) { gpc_polygon *ret, *lop, *rop, *tmp, *p = self->p; int i; if (p->num_contours <= 0) { Py_INCREF(Py_None); return Py_None; } if (! (lop = poly_p_new())) return Polygon_Raise(ERR_MEM); if (! (rop = poly_p_new())) return Polygon_Raise(ERR_MEM); if (! (ret = poly_p_new())) return Polygon_Raise(ERR_MEM); /* find first contour which is not a hole */ i = 0; while ((i < p->num_contours) && (p->hole[i] == 1)) i++; if (i < p->num_contours) gpc_add_contour(lop, p->contour+i, 1); /* then try to add other contours */ for (i++; i < p->num_contours; i++) { if (p->hole[i] == 0) { gpc_free_polygon(rop); gpc_free_polygon(ret); gpc_add_contour(rop, (p->contour+i), 0); gpc_polygon_clip(GPC_UNION, lop, rop, ret); tmp = lop; lop = ret; ret = tmp; } } /* then try to cut out holes */ for (i = 0; i < p->num_contours; i++) { if (p->hole[i] == 1) { gpc_free_polygon(rop); gpc_free_polygon(ret); gpc_add_contour(rop, (p->contour+i), 0); gpc_polygon_clip(GPC_DIFF, lop, rop, ret); tmp = lop; lop = ret; ret = tmp; } } gpc_free_polygon(self->p); free(self->p); self->p = lop; gpc_free_polygon(ret); free(ret); gpc_free_polygon(rop); free(rop); self->bbValid = 0; return Py_BuildValue("O", Py_None); }
void poly2tri_gpc(double** xout, double** yout, size_t* nout, const double* xin, const double* yin, size_t nin) { int i, j, k; gpc_polygon p; gpc_tristrip t; /* Fill in the gpc contour. */ p.num_contours = 1; p.hole = (int*) malloc(1 * sizeof(int)); p.hole[0] = 0; p.contour = (gpc_vertex_list*) malloc(1 * sizeof(gpc_vertex_list)); p.contour[0].num_vertices = nin; p.contour[0].vertex = (gpc_vertex*) malloc(nin * sizeof(gpc_vertex)); for (i = 0; i < nin; i++) { p.contour[0].vertex[i].x = xin[i]; p.contour[0].vertex[i].y = yin[i]; } /* Convert the polygon to a list of triangle strips. */ t.num_strips = 0; t.strip = NULL; gpc_polygon_to_tristrip(&p, &t); /* Take out the triangles from the triangle strips. */ *nout = 0; for (i = 0; i < t.num_strips; i++) *nout += t.strip[i].num_vertices - 2; *xout = (double*) mxMalloc(*nout * 3 * sizeof(double)); *yout = (double*) mxMalloc(*nout * 3 * sizeof(double)); for (k = 0, i = 0; i < t.num_strips; i++) for (j = 2; j < t.strip[i].num_vertices; j++) { (*xout)[k] = t.strip[i].vertex[j-2].x; (*yout)[k++] = t.strip[i].vertex[j-2].y; (*xout)[k] = t.strip[i].vertex[j-1].x; (*yout)[k++] = t.strip[i].vertex[j-1].y; (*xout)[k] = t.strip[i].vertex[j].x; (*yout)[k++] = t.strip[i].vertex[j].y; } /* Free the gpc polygon and triangle strip. */ gpc_free_tristrip(&t); gpc_free_polygon(&p); }
static PyObject *Polygon_overlaps(Polygon *self, Polygon *other) { double x0, x1, y0, y1, X0, X1, Y0, Y1; gpc_polygon * pres; int r; if (! Polygon_Check(other)) return Polygon_Raise(ERR_ARG); Polygon_getBoundingBox(self, &x0, &x1, &y0, &y1); Polygon_getBoundingBox(other, &X0, &X1, &Y0, &Y1); /* first test if bounding box overlaps other boundingbox */ if ((X0 > x1) || (x0 > X1) || (Y0 > y1) || (y0 > Y1)) return Py_BuildValue("i", 0); /* still there? Let's do the full test... */ if (! (pres = poly_p_new())) return Polygon_Raise(ERR_MEM); gpc_polygon_clip(GPC_INT, other->p, self->p, pres); r = pres->num_contours; gpc_free_polygon(pres); free(pres); return Py_BuildValue("i", ((r > 0) ? 1 : 0)); }
static PyObject *Polygon_covers(Polygon *self, Polygon *other) { double x0, x1, y0, y1, X0, X1, Y0, Y1; gpc_polygon * pres; int r; if (! Polygon_Check(other)) return Polygon_Raise(ERR_ARG); Polygon_getBoundingBox(self, &x0, &x1, &y0, &y1); Polygon_getBoundingBox(other, &X0, &X1, &Y0, &Y1); /* first test if bounding box covers other boundingbox */ if ((X0 < x0) || (X1 > x1) || (Y0 < y0) || (Y1 > y1)) Py_RETURN_FALSE; /* still there? Let's do the full test... */ if (! (pres = poly_p_new())) return Polygon_Raise(ERR_MEM); gpc_polygon_clip(GPC_DIFF, other->gpc_p, self->gpc_p, pres); r = pres->num_contours; gpc_free_polygon(pres); free(pres); if (r > 0) Py_RETURN_FALSE; else Py_RETURN_TRUE; }
void clo_clipdone ( int *iret ) /************************************************************************ * clo_clipdone * * * * This routine releases previous allocated memory in this module * * * * void clo_clipdone ( iret ) * * * * Input parameters: * * None * * * * Output parameters: * * *iret int Return code * * = 0: normal * * * ** * * Log: * * B. Yin/SAIC 9/04 Created * ***********************************************************************/ { gpc_free_polygon ( &gpc_poly_results ); *iret = 0; }
SEXP Rgpc_polygon_to_tristrip(SEXP poly) { gpc_polygon subject; gpc_tristrip tristrip; int nsubj; SEXP strip, returnval; double *xsubjpoly; PROTECT(poly = AS_NUMERIC(poly)); nsubj = LENGTH(poly); xsubjpoly = NUMERIC_POINTER(poly); double_to_gpc_polygon(&subject, xsubjpoly, nsubj); gpc_polygon_to_tristrip(&subject, &tristrip); PROTECT(returnval = NEW_LIST(tristrip.num_strips)); for (int i=0; i < tristrip.num_strips; i++) { double *xstrip; SET_VECTOR_ELT(returnval, i, strip = NEW_NUMERIC(2*tristrip.strip[i].num_vertices)); xstrip = REAL(strip); for (int j=0; j < tristrip.strip[i].num_vertices; j++) { xstrip[2*j] = tristrip.strip[i].vertex[j].x; xstrip[2*j+1] = tristrip.strip[i].vertex[j].y; } } gpc_free_polygon(&subject); gpc_free_tristrip(&tristrip); UNPROTECT(2); return(returnval); }
/* delete Polygon */ static void Polygon_dealloc(Polygon *self) { gpc_free_polygon(self->gpc_p); free(self->gpc_p); Py_XDECREF(self->attr); self->ob_type->tp_free((PyObject*)self); }
static void Polygon_dealloc(Polygon *self) { gpc_free_polygon(self->p); free(self->p); Py_XDECREF(self->attr); PyMem_Del(self); }
// make a gpc_polygon for a closed polyline contour // approximates arcs with multiple straight-line segments // if icontour = -1, make polygon with all contours, // combining intersecting contours if possible // returns data on arcs in arc_array // int CPolyLine::MakeGpcPoly( int icontour, CArray<CArc> * arc_array ) { if( m_gpc_poly->num_contours ) FreeGpcPoly(); if( !GetClosed() && (icontour == (GetNumContours()-1) || icontour == -1)) return 1; // error // initialize m_gpc_poly m_gpc_poly->num_contours = 0; m_gpc_poly->hole = NULL; m_gpc_poly->contour = NULL; int n_arcs = 0; int first_contour = icontour; int last_contour = icontour; if( icontour == -1 ) { first_contour = 0; last_contour = GetNumContours() - 1; } if( arc_array ) arc_array->SetSize(0); int iarc = 0; for( int icont=first_contour; icont<=last_contour; icont++ ) { // make gpc_polygon for this contour gpc_polygon * gpc = new gpc_polygon; gpc->num_contours = 0; gpc->hole = NULL; gpc->contour = NULL; // first, calculate number of vertices in contour int n_vertices = 0; int ic_st = GetContourStart(icont); int ic_end = GetContourEnd(icont); for( int ic=ic_st; ic<=ic_end; ic++ ) { int style = side_style[ic]; int x1 = corner[ic].x; int y1 = corner[ic].y; int x2, y2; if( ic < ic_end ) { x2 = corner[ic+1].x; y2 = corner[ic+1].y; } else { x2 = corner[ic_st].x; y2 = corner[ic_st].y; } if( style == STRAIGHT ) n_vertices++; else { // style is ARC_CW or ARC_CCW int n; // number of steps for arcs n = (abs(x2-x1)+abs(y2-y1))/(CArc::MAX_STEP); n = max( n, CArc::MIN_STEPS ); // or at most 5 degrees of arc n_vertices += n; n_arcs++; } } // now create gcp_vertex_list for this contour gpc_vertex_list * g_v_list = new gpc_vertex_list; g_v_list->vertex = (gpc_vertex*)calloc( sizeof(gpc_vertex), n_vertices ); g_v_list->num_vertices = n_vertices; int ivtx = 0; for( int ic=ic_st; ic<=ic_end; ic++ ) { int style = side_style[ic]; int x1 = corner[ic].x; int y1 = corner[ic].y; int x2, y2; if( ic < ic_end ) { x2 = corner[ic+1].x; y2 = corner[ic+1].y; } else { x2 = corner[ic_st].x; y2 = corner[ic_st].y; } if( style == STRAIGHT ) { g_v_list->vertex[ivtx].x = x1; g_v_list->vertex[ivtx].y = y1; ivtx++; } else { // style is arc_cw or arc_ccw int n; // number of steps for arcs n = (abs(x2-x1)+abs(y2-y1))/(CArc::MAX_STEP); n = max( n, CArc::MIN_STEPS ); // or at most 5 degrees of arc double xo, yo, theta1, theta2, a, b; a = fabs( (double)(x1 - x2) ); b = fabs( (double)(y1 - y2) ); if( style == CPolyLine::ARC_CW ) { // clockwise arc (ie.quadrant of ellipse) int i=0, j=0; if( x2 > x1 && y2 > y1 ) { // first quadrant, draw second quadrant of ellipse xo = x2; yo = y1; theta1 = pi; theta2 = pi/2.0; } else if( x2 < x1 && y2 > y1 ) { // second quadrant, draw third quadrant of ellipse xo = x1; yo = y2; theta1 = 3.0*pi/2.0; theta2 = pi; } else if( x2 < x1 && y2 < y1 ) { // third quadrant, draw fourth quadrant of ellipse xo = x2; yo = y1; theta1 = 2.0*pi; theta2 = 3.0*pi/2.0; } else { xo = x1; // fourth quadrant, draw first quadrant of ellipse yo = y2; theta1 = pi/2.0; theta2 = 0.0; } } else { // counter-clockwise arc int i=0, j=0; if( x2 > x1 && y2 > y1 ) { xo = x1; // first quadrant, draw fourth quadrant of ellipse yo = y2; theta1 = 3.0*pi/2.0; theta2 = 2.0*pi; } else if( x2 < x1 && y2 > y1 ) { xo = x2; // second quadrant yo = y1; theta1 = 0.0; theta2 = pi/2.0; } else if( x2 < x1 && y2 < y1 ) { xo = x1; // third quadrant yo = y2; theta1 = pi/2.0; theta2 = pi; } else { xo = x2; // fourth quadrant yo = y1; theta1 = pi; theta2 = 3.0*pi/2.0; } } // now write steps for arc if( arc_array ) { arc_array->SetSize(iarc+1); (*arc_array)[iarc].style = style; (*arc_array)[iarc].n_steps = n; (*arc_array)[iarc].xi = x1; (*arc_array)[iarc].yi = y1; (*arc_array)[iarc].xf = x2; (*arc_array)[iarc].yf = y2; iarc++; } for( int is=0; is<n; is++ ) { double theta = theta1 + ((theta2-theta1)*(double)is)/n; double x = xo + a*cos(theta); double y = yo + b*sin(theta); if( is == 0 ) { x = x1; y = y1; } g_v_list->vertex[ivtx].x = x; g_v_list->vertex[ivtx].y = y; ivtx++; } } } if( n_vertices != ivtx ) ASSERT(0); // add vertex_list to gpc gpc_add_contour( gpc, g_v_list, 0 ); // now clip m_gpc_poly with gpc, put new poly into result gpc_polygon * result = new gpc_polygon; if( icontour == -1 && icont != 0 ) gpc_polygon_clip( GPC_DIFF, m_gpc_poly, gpc, result ); // hole else gpc_polygon_clip( GPC_UNION, m_gpc_poly, gpc, result ); // outside // now copy result to m_gpc_poly gpc_free_polygon( m_gpc_poly ); delete m_gpc_poly; m_gpc_poly = result; gpc_free_polygon( gpc ); delete gpc; free( g_v_list->vertex ); free( g_v_list ); } return 0; }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { unsigned int i,j,n1,n2,c,v,m; double* volume; double* b1; double* b2; unsigned int joffset; double zOverlap; double areaOverlap; double* result_vertex; gpc_polygon subject, clip, result; gpc_vertex_list subject_contour; gpc_vertex_list clip_contour; int hole = 0; subject.num_contours = 1; subject.hole = &hole; subject.contour = &subject_contour; subject.contour[0].num_vertices = 4; clip.num_contours = 1; clip.hole = &hole; clip.contour = &clip_contour; clip.contour[0].num_vertices = 4; n2 = mxGetN(prhs[0]); n1 = mxGetN(prhs[1]); b2 = mxGetPr(prhs[0]); b1 = mxGetPr(prhs[1]); plhs[0] = mxCreateNumericMatrix(n2, n1, mxDOUBLE_CLASS, mxREAL); volume = (double*) mxGetData(plhs[0]); for (i=0; i<n1; ++i){ /* subject */ subject.contour[0].vertex = (gpc_vertex *)b1; for (j=0; j<n2; ++j){ joffset = 10*j; zOverlap = MIN(b1[9],b2[joffset+9]) - MAX(b1[8],b2[joffset+8]); if (zOverlap>0){ /* get intersection */ clip.contour[0].vertex = (gpc_vertex *)(b2+joffset); gpc_polygon_clip(1, &subject, &clip, &result); if (result.num_contours>0 && result.contour[0].num_vertices > 2) { /* compute area of intersection */ /* * http://www.mathopenref.com/coordpolygonarea.html * Green's theorem for the functions -y and x; http://stackoverflow.com/questions/451426/how-do-i-calculate-the-surface-area-of-a-2d-polygon */ result_vertex = (double*)(result.contour[0].vertex); m = result.contour[0].num_vertices; areaOverlap = (result_vertex[2*m-2]*result_vertex[1]-result_vertex[2*m-1]*result_vertex[0]); for (v= 1; v < m; v++) { areaOverlap += (result_vertex[v*2-2]*result_vertex[v*2+1]-result_vertex[v*2-1]*result_vertex[v*2]); } *volume = zOverlap * 0.5 * fabs(areaOverlap); } gpc_free_polygon(&result); } ++volume; } b1+=10; } /* gpc_free_polygon(&subject); gpc_free_polygon(&clip); mxFree(subject.hole); mxFree(subject.contour); mxFree(clip.hole); mxFree(clip.contour); **/ }
void clo_clip ( int *np, float *xp, float *yp, char *sysp, char *bounds, char *name, int *nclip, int *maxpts, int *iret ) /************************************************************************ * clo_clip * * * * This routine performs clipping of a polygon against a specified * * bounds area. * * * * void clo_clip ( np, xp, yp, sysp, bounds, name, nclip, * * maxpts, iret ) * * * * Input parameters: * * *np int Number of polygon points * * *xp float X array of polygon points * * *yp float Y array of polygon points * * *sysp char Polygon points coordinate system* * *bounds char Bounds name * * *name char Clipping area tag * * * * Output parameters: * * *nclip int Number of resulting contours * * *maxpts int Maximum number of points for any* * contour in the resulting polygon* * *iret int Return code * * = 0: normal * * * ** * * Log: * * B. Yin/SAIC 9/04 Created * ***********************************************************************/ { int ier, ii; float *xnormal, *ynormal; gpc_polygon gpc_poly, gpc_poly_bnds, gpc_poly_tmp; gpc_vertex_list verts; /*---------------------------------------------------------------------*/ strcpy ( sysin, sysp ); /* * Convert incoming coordinate system to sys_N (normalized). */ G_MALLOC ( xnormal, float, *np, "CLO_CLIP: xnormal" ); G_MALLOC ( ynormal, float, *np, "CLO_CLIP: ynormal" ); gtrans ( sysp, sys_N, np, xp, yp, xnormal, ynormal, &ier, strlen(sysp), strlen(sys_N) ); /* * Fill GPC polygon structure with incoming points. */ gpc_poly.num_contours = 0; gpc_poly.hole = (int*)NULL; gpc_poly.contour = (gpc_vertex_list*)NULL; verts.vertex = (gpc_vertex*)NULL; verts.num_vertices = 0; gpc_cvlist ( *np, xnormal, ynormal, &verts, &ier ); gpc_add_contour ( &gpc_poly, &verts, G_FALSE ); /* * Create a GPC polygon for the bounds. */ clo_clipbnds ( bounds, name, &gpc_poly_bnds, &ier ); /* * Clip */ gpc_polygon_clip ( GPC_INT, &gpc_poly, &gpc_poly_bnds, &gpc_poly_tmp ); /* * Remove holes. Holes are ignored in this release. */ gpc_poly_results.num_contours = 0; gpc_poly_results.hole = (int*)NULL; gpc_poly_results.contour = (gpc_vertex_list*)NULL; for ( ii = 0; ii < gpc_poly_tmp.num_contours; ii++ ) { if ( gpc_poly_tmp.hole [ ii ] == G_FALSE ) { gpc_add_contour ( &gpc_poly_results, &gpc_poly_tmp.contour [ ii ], G_FALSE ); } } /* * Get the number of contours in the resulting polygon * and the maximum number of pointers of any contour */ *nclip = gpc_poly_results.num_contours; *maxpts = 0; for ( ii = 0; ii < *nclip; ii++ ) { *maxpts = MAX ( *maxpts, gpc_poly_results.contour [ ii ].num_vertices ); } /* * Release memory */ gpc_free_polygon ( &gpc_poly_bnds ); gpc_free_polygon ( &gpc_poly_tmp ); gpc_free_polygon ( &gpc_poly ); free ( verts.vertex ); G_FREE ( xnormal, float ); G_FREE ( ynormal, float ); *iret = 0; }
int main ( void ) /************************************************************************ * TESTGPC * * * * This program tests the GPC contributed library public functions. * * * ** * * Log: * * D.W.Plummer/NCEP 2/04 * * D.W.Plummer/NCEP 10/06 Added GPC_SET_EPSILON * ***********************************************************************/ { int ii, cont, numsub, which, ier; int operation, readholeflag, writeholeflag, hole; int nverts=0; double e; char select[8]; float xv[LLMXPT], yv[LLMXPT]; char filnam[256], buffer[80]; int pagflg; char errgrp[8]; FILE *fpread, *fpwrite; gpc_polygon subject_polygon, clip_polygon, result_polygon; gpc_vertex_list contour; /*---------------------------------------------------------------------*/ cont = G_FALSE; /* * Structure initializations. */ subject_polygon.num_contours = 0; subject_polygon.hole = (int*)NULL; subject_polygon.contour = (gpc_vertex_list*)NULL; clip_polygon.num_contours = 0; result_polygon.num_contours = 0; contour.vertex = (gpc_vertex*)NULL; contour.num_vertices = 0; while ( cont == G_FALSE ) { printf ( "\n\n" ); printf ( "*** ORIGINAL GPC PUBLIC FUNCTIONS ***\n"); printf ( " 1 = GPC_READ_POLYGON 2 = GPC_WRITE_POLYGON \n"); printf ( " 3 = GPC_ADD_CONTOUR 4 = GPC_POLYGON_CLIP \n"); printf ( " 5 = GPC_FREE_POLYGON \n"); printf ( "*** GPC PUBLIC FUNCTION ADD-ONS ***\n"); printf ( " 11 = GPC_CREATE_VERTEX_LIST \n"); printf ( " 12 = GPC_GET_VERTEX_LIST \n"); printf ( " 13 = GPC_GET_VERTEX_AREA \n"); printf ( " 14 = GPC_SET_EPSILON \n"); printf ( "*** HELP ***\n"); printf ( " 99 = HELP on INPUT FILE FORMATS \n"); printf ( "\n" ); printf ( "Select a subroutine number or type EXIT: " ); scanf ( " %s", select ); switch ( select[0] ) { case 'e': case 'E': cont = G_TRUE; default: numsub = atoi ( select ); break; } /*---------------------------------------------------------------------*/ if ( numsub == 1 ) { printf("Make sure your polygon file is in the proper format:\n"); printf("<num-contours>\n"); printf("<num-vertices-in-first-contour>\n"); printf("[<first-contour-hole-flag>]\n"); printf("<vertex-list>\n"); printf("<num-vertices-in-second-contour>\n"); printf("[<second-contour-hole-flag>]\n"); printf("<vertex-list> \n"); printf("etc...\n"); printf ( "Enter filename to read polygon from : \n"); scanf ( " %s", filnam ); printf ( "Enter whether file format contains hole flags (%d-FALSE,%d-TRUE) :\n", G_FALSE, G_TRUE ); scanf ( " %d", &readholeflag ); printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP) :\n", SUBJECT, CLIP ); scanf ( " %d", &which ); fpread = (FILE *)cfl_ropn ( filnam, "", &ier ); if ( ier == G_NORMAL ) { if ( which == SUBJECT ) gpc_read_polygon ( fpread, readholeflag, &subject_polygon ); else if ( which == CLIP ) gpc_read_polygon ( fpread, readholeflag, &clip_polygon ); else printf("Invalid polygon type\n"); cfl_clos ( fpread, &ier ); } else { printf("Unable to open file %s\n", filnam ); } } /*---------------------------------------------------------------------*/ if ( numsub == 2 ) { printf ( "Enter filename to write polygon to : \n"); scanf ( " %s", filnam ); printf ( "Enter the write hole flag (%d-FALSE,%d-TRUE):\n", G_FALSE, G_TRUE ); scanf ( " %d", &writeholeflag ); printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP,%d-RESULT):\n", SUBJECT, CLIP, RESULT ); scanf ( " %d", &which ); fpwrite = (FILE *)cfl_wopn ( filnam, &ier ); if ( ier == G_NORMAL ) { if ( which == SUBJECT ) gpc_write_polygon ( fpwrite, writeholeflag, &subject_polygon ); else if ( which == CLIP ) gpc_write_polygon ( fpwrite, writeholeflag, &clip_polygon ); else if ( which == RESULT ) gpc_write_polygon ( fpwrite, writeholeflag, &result_polygon ); else printf("Invalid polygon type\n"); cfl_clos ( fpwrite, &ier ); } else { printf("Unable to open file %s\n", filnam ); } } /*---------------------------------------------------------------------*/ if ( numsub == 3 ) { if ( nverts == 0 ) { printf("Must first create a vertex list (option 11)\n"); } else { printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP,%d-RESULT) to add vertex list to:\n", SUBJECT, CLIP, RESULT ); scanf ( " %d", &which ); printf ( "Enter the hole flag (%d-HOLE,%d-NOT A HOLE):\n", G_TRUE, G_FALSE ); scanf ( " %d", &hole ); if ( which == SUBJECT ) { gpc_add_contour ( &subject_polygon, &contour, hole ); } else if ( which == CLIP ) { gpc_add_contour ( &clip_polygon, &contour, hole ); } else { printf("Invalid polygon\n"); } } } /*---------------------------------------------------------------------*/ if ( numsub == 4 ) { printf ( "Enter operation (%d-GPC_DIFF,%d-GPC_INT,%d-GPC_XOR,%d-GPC_UNION):\n", GPC_DIFF, GPC_INT, GPC_XOR, GPC_UNION ); scanf ( " %d", &operation ); gpc_polygon_clip ( operation, &subject_polygon, &clip_polygon, &result_polygon ); } /*---------------------------------------------------------------------*/ if ( numsub == 5 ) { printf ( "Enter which polygon (%d-SUBJECT,%d-CLIP,%d-RESULT,%d-ALL) to free contours:\n ", SUBJECT, CLIP, RESULT, ALL ); scanf ( " %d", &which ); if ( which == SUBJECT || which == ALL ) { if ( subject_polygon.num_contours != 0 ) gpc_free_polygon ( &subject_polygon ); } else if ( which == CLIP || which == ALL ) { if ( clip_polygon.num_contours != 0 ) gpc_free_polygon ( &clip_polygon ); } else if ( which == RESULT || which == ALL ) { if ( result_polygon.num_contours != 0 ) gpc_free_polygon ( &result_polygon ); } } /*---------------------------------------------------------------------*/ if ( numsub == 11 ) { printf ( "Enter either the number of points in polygon (to be followed by entering the points), or a filename to read points from: \n"); scanf ( " %s", filnam ); cst_numb ( filnam, &nverts, &ier ); if ( ier == 0 ) { for ( ii = 0; ii < nverts; ii++ ) scanf ( "%f %f", &(xv[ii]), &(yv[ii]) ); if ( contour.vertex != (gpc_vertex*)NULL ) free ( contour.vertex ); gpc_cvlist ( nverts, xv, yv, &contour, &ier ); } else { printf ( "Note that the file format is simply a list of coordinate pairs separated by whitespace.\nThe number of points will be counted automatically. For instance, a file containing:\n0 0\n0 1\n1 1\nyields a vertex list of three points.\n\n"); nverts = 0; fpread = (FILE *)cfl_tbop ( filnam, "", &ier ); if ( ier == G_NORMAL ) { cfl_trln ( fpread, sizeof(buffer), buffer, &ier ); while ( ier == 0 ) { sscanf ( buffer, "%f %f", &(xv[nverts]), &(yv[nverts]) ); nverts += 1; cfl_trln ( fpread, sizeof(buffer), buffer, &ier ); } printf("EOF reached in file %s, number of vertices = %d\n", filnam, nverts ); cfl_clos( fpread, &ier ); if ( contour.vertex != (gpc_vertex*)NULL ) free ( contour.vertex ); gpc_cvlist ( nverts, xv, yv, &contour, &ier ); } } } /*---------------------------------------------------------------------*/ if ( numsub == 12 ) { gpc_gvlist ( &contour, &nverts, xv, yv, &ier ); printf("gpc_gvlist, ier = %d\n", ier ); printf("Number of vertices = %d\n", nverts ); for ( ii = 0; ii < nverts; ii++ ) printf ( "%d - %f %f\n", ii, xv[ii], yv[ii] ); } /*---------------------------------------------------------------------*/ if ( numsub == 13 ) { printf ( "Area of contour is %f\n", gpc_gvarea(&contour) ); } /*---------------------------------------------------------------------*/ if ( numsub == 14 ) { scanf ( " %lf", &e ); gpc_set_epsilon ( e ); } /*---------------------------------------------------------------------*/ if ( numsub == 99 ) { pagflg = G_FALSE; strcpy ( errgrp, "TESTGPC" ); ip_help ( errgrp, &pagflg, &ier, strlen(errgrp) ); } /*---------------------------------------------------------------------*/ } if ( subject_polygon.num_contours != 0 ) gpc_free_polygon ( &subject_polygon ); if ( clip_polygon.num_contours != 0 ) gpc_free_polygon ( &clip_polygon ); if ( result_polygon.num_contours != 0 ) gpc_free_polygon ( &result_polygon ); if ( contour.vertex != (gpc_vertex*)NULL ) free ( contour.vertex ); return(0); }
static int Lgc(lua_State *L) { gpc_polygon *p=Pget(L,1); gpc_free_polygon(p); return 0; }
void clo_blasso ( char *bndtyp, char *key, int *npts, char *btags, gpc_polygon *union_poly, int *iret ) /************************************************************************ * clo_blasso * * * * This function takes a string of bound tags, semi-colon separated, and* * returns a polygon structure from the union of the polygons designated* * by the bound tags. A return code of 1 due to a bad bounds key tag * * could mean the tag name (eg., <FIPS>) is invalid and/or the tag value* * (eg., 51059 -- a FIPS code) is invalid. Processing continues, so the* * invoking routine may also want to check the number of polygons for 0,* * in which case it would most likely be caused by an invalid tag name. * * * * Note that the tag name may or may not be enclosed with '<' and '>'. * * If it is not, they will be added to the tag name. * * * * clo_blasso ( bndtyp, key, npts, btags, union_poly, iret ) * * * * Input parameters: * * *bndtyp char Bounds file alias name (eg., WBCMZ_BNDS)* * *key char Search tag name in bounds file * * (eg., <FIPS> or FIPS, <STATE> or STATE)* * *npts int No. of bounds tag values in string btags* * *btags char Bounds tag values, delimited by ";" * * (eg., 51059;51057;51053) * * * * Output parameters: * * *union_poly gpc_polygon GPC polygon structure of union * * iret int Return code * * = 0 Normal * * = 1 No bound area found for a tag * * due to bad tag name or value * * = -1 Bounds file open error return * * or illegal bounds name * * * ** * * Log: * * F. J. Yen/NCEP 1/05 * * F. J. Yen/NCEP 2/05 Increased size of btagkey; Enclosed tag * * name with '<' and '>' if missing. * * J. Wu/SAIC 6/05 remove reference to LLMXPT * * F.Yen&D.Plummer/NCEP 7/05 Redesigned for performance. * * D.W.Plummer/NCEP 8/05 Add final GPC_UNION to rm spurious pts * ***********************************************************************/ { char **arrptr, btagkey[80]; char *tag_start = { "<" }; char *tag_end = { ">" }; int ii, maxexp, minp, ier, ierro, mxpts, end; int narr, numTmp, len, hole, initl; float *xTmp, *yTmp; float rlatmn, rlonmn, dlatmx, dlonmx, filter; gpc_polygon polygon; gpc_vertex_list verts; /*---------------------------------------------------------------------*/ *iret = 0; ier = 0; minp = 0; hole = 0; filter = 0.0; maxexp = 400; /* * Initalize the gpc polygon structure variables */ union_poly->num_contours = 0; union_poly->hole = (int *)NULL; union_poly->contour = (gpc_vertex_list *)NULL; clo_bstype ( bndtyp , &ier ); /* Set the bounds file */ if ( ier != 0 ) { *iret = -1; return; } /* * Set the bounds area */ rlatmn = -90.0; dlatmx = +90.0; rlonmn = -180.0; dlonmx = +180.0; clo_bsarea ( &rlatmn, &rlonmn, &dlatmx, &dlonmx, &ier ); /* * Initialize the clo library */ clo_init ( &ier); /* * Allocate memory */ clo_qmxpts ( "BOUNDS", &mxpts, &ier ); G_MALLOC ( xTmp, float, mxpts, "CLO_BLASSO" ); G_MALLOC ( yTmp, float, mxpts, "CLO_BLASSO" ); /* * Break apart the bounds tag values */ arrptr = (char **)malloc(*npts * sizeof(char *)); for (ii = 0; ii < *npts; ii++) { arrptr[ii] = (char *) malloc(maxexp); } cst_clst ( btags, ';', " ", *npts, maxexp, arrptr, &narr, &ier ); /* * initialize single bounds polygon */ polygon.num_contours = 0; polygon.hole = (int *)NULL; polygon.contour = (gpc_vertex_list *)NULL; /* * Loop over bounds tag values */ for (ii=0;ii < narr; ii++) { cst_rmbl ( arrptr[ii], arrptr[ii], &len, &ier ); if ( len > 0 ) { ierro = 0; /* * Create the key tag to search on ( eg. <FIPS>51097 ). First, * check for '<' at beginning of tag. Add it if it isn't there. */ btagkey[0] = '\0'; if( key[0] != '<' ) { strcpy( btagkey, tag_start ); } strcat ( btagkey, key ); /* * Check for '>' at end of key tag. Add it if it isn't there. */ end = strlen ( key ); if ( key [ end - 1 ] != '>' ) { strcat ( btagkey, tag_end ); } strcat ( btagkey, arrptr[ii]); clo_bstype ( bndtyp , &ier ); /* Set the bounds file */ clo_bstag ( btagkey, &ier ); /* Set the bounds key tag (eg <FIPS>51097 ) */ /* * Find the bound key tag polygon */ initl = 1; while ( ierro == 0 ) { /* * Get next bounds */ clo_bgnext (&minp, &mxpts, &filter, &numTmp, xTmp, yTmp, &ierro ); if ( initl == 1 ) { initl = 0; if ( ierro != 0 ) { /* * No bound area (polygon) found for current bounds * key tag in btagkey due to either an invalid tag * name (eg, <FIPS> or <STATE>) and/or invalid tag * value (ie, if the tag name is <FIPS>, the tag * value would be a FIPS code such as 13009). */ *iret = 1; } } if ( ierro == 0 ) { /* * initialize vertex list */ verts.vertex = (gpc_vertex*)NULL; verts.num_vertices =0; gpc_cvlist (numTmp, xTmp, yTmp, &verts, &ier ); gpc_add_contour ( &polygon, &verts, hole); free ( verts.vertex ); } } /* end for while loop */ } /* end for length check */ } /* end for loop */ /* * union the polygon with a NULL polygon (union) to get the union */ gpc_polygon_clip (GPC_UNION, &polygon, union_poly, union_poly ); gpc_free_polygon ( &polygon); gpc_polygon_clip (GPC_UNION, &polygon, union_poly, union_poly ); /* * Free memory space. */ G_FREE ( xTmp, float ); G_FREE ( yTmp, float ); for ( ii = 0; ii < *npts; ii++ ) { free ( arrptr[ii] ); } free ( arrptr); }
int main (int argc, char **argv) { struct st_01 { char file[256]; }; struct st_02 { FILE *file; }; struct header_01 { int version; int pasx; int pasy; int xmin; int ymin; int xmax; int ymax; int p1; int p2; int p3; int p4; int p5; }; struct st_02 file_end[4]; char bd_path[256]; char gpc_path[256]; char gpc_file[256]; struct st_01 bd_end[4]; int pas[] = {45, 15, 5, 1}; int level = 3; int i; int pos_data; int tab_data; int x, y; int c; struct header_01 header_end[4]; FILE *polygon_file; gpc_polygon polygon; int n_contour; int n_point; if (argc < 2 || argc > 3) { fprintf (stderr, "Sorry !!\n"); fprintf (stderr, "Usage: read_bd [f|h|i|l|c]\n\n"); exit (EXIT_FAILURE); } pos_data = 0; sprintf(bd_path, "./bd/bd_%s", argv[1]); for (i=0; i<=level; i++) { printf("i: %d\n", i); sprintf(bd_end[i].file, "%s/poly-%s-%d.dat", bd_path, argv[1], pas[i]); if ((file_end[i].file = fopen (bd_end[i].file, "wb")) == NULL ) { fprintf (stderr, "Impossible d'ouvrir le fichier %s\n", bd_end[i].file); exit (EXIT_FAILURE); } header_end[i].version= 234; header_end[i].pasx= pas[i]; header_end[i].pasy= pas[i]; header_end[i].xmin= 0; header_end[i].ymin= -90; header_end[i].xmax= 360; header_end[i].ymax= 90; header_end[i].p1= 1; header_end[i].p2= 2; header_end[i].p3= 3; header_end[i].p4= 4; header_end[i].p5= 5; fwrite(&header_end[i], sizeof(header_end[i]), 1, file_end[i].file); for (x=0; x<360; x=x+pas[i]) { for (y=-90; y<90; y=y+pas[i]) { fwrite(&pos_data, sizeof(int), 1, file_end[i].file); } } for (x=0; x<360; x=x+pas[i]) { printf("X=%d\n",x); for (y=-90; y<90; y=y+pas[i]) { if (get_gpc_path(gpc_path, bd_path, x, y, pas, i) != 0) { fseek(file_end[i].file, 0L, SEEK_END); pos_data = ftell(file_end[i].file); //printf("pos_data: %d\n", pos_data); for (c=1; c<=5; c=c+1) { sprintf(gpc_file, "%s/%s%d.dat", gpc_path, argv[1], c); //printf("X: %i, Y: %i, File: %s\n", x, y, gpc_file); if ((polygon_file = fopen(gpc_file, "r")) == NULL ) { fprintf (stderr, "Impossible d'ouvrir le fichier %s\n", gpc_file); exit (EXIT_FAILURE); } gpc_read_polygon(polygon_file, 1, &polygon); /* Lecture du fichier polygone*/ //printf("num_contour: %d\n", polygon.num_contours); fwrite(&polygon.num_contours, sizeof(int), 1, file_end[i].file); for (n_contour=0; n_contour<polygon.num_contours; n_contour++) { fwrite(&polygon.hole[n_contour], sizeof(int), 1, file_end[i].file); fwrite(&polygon.contour[n_contour].num_vertices, sizeof(int), 1, file_end[i].file); for (n_point=0; n_point<polygon.contour[n_contour].num_vertices; n_point++) { fwrite(&polygon.contour[n_contour].vertex[n_point].x, sizeof(double), 1, file_end[i].file); fwrite(&polygon.contour[n_contour].vertex[n_point].y, sizeof(double), 1, file_end[i].file); } } fclose(polygon_file); gpc_free_polygon(&polygon); } tab_data = (x/pas[i])*(180/pas[i]) + (y+90)/pas[i]; //printf("tab_data: %d\n\n", tab_data); fseek(file_end[i].file, sizeof(header_end[i]) + tab_data*sizeof(int), SEEK_SET); //erreur + tab_data*sizeof(long) fwrite(&pos_data, sizeof(int), 1, file_end[i].file); } } } fclose(file_end[i].file); } return 0; }
Polygon2d::~Polygon2d() { gpc_free_tristrip(&strip); gpc_free_polygon(&polygon); }