// 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; } }
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 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 ); }
static PyObject *Polygon_opUnion(Polygon *self, Polygon *other) { gpc_polygon *ret; if (! Polygon_Check(other)) return Polygon_Raise(ERR_TYP); if (! (ret = poly_p_new())) return Polygon_Raise(ERR_MEM); gpc_polygon_clip(GPC_UNION, self->p, other->p, ret); return (PyObject *)Polygon_NEW(ret); }
static int Pclip(lua_State *L, int op) { gpc_polygon *p=Pget(L,1); gpc_polygon *q=Pget(L,2); gpc_polygon *r=Pnew(L); gpc_polygon_clip(op,p,q,r); return 1; }
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; }
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); }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { gpc_polygon subject, clip, result; mwSize dims[2], GPC_ARG; const char *field_names[] = {"x","y","hole"}; if (nrhs == 0) { mexPrintf("\nOutPol = PolygonClip(RefPol, ClipPol, [type]);\n\n"); mexPrintf("All polygons are structures with the fields ...\n"); mexPrintf(" .x: x-coordinates of contour\n"); mexPrintf(" .y: y-coordinates of contour\n"); mexPrintf(" .hole: hole flag\n"); mexPrintf("\nEvery polygon may contain several contours (s.example). Optional type parameter selects method:\n"); mexPrintf("0 - Diff\n"); mexPrintf("1 - And (Standard)\n"); mexPrintf("2 - Xor\n"); mexPrintf("3 - Union\n"); mexPrintf("\nPolygon Clipping Routine based on gpc2.32. Credit goes to ...\n"); mexPrintf("Alan Murta, Advanced Interfaces Group, Department of Computer Science, University of Manchester\n"); mexPrintf("http://www.cs.man.ac.uk/~toby/alan/software//\n\n"); return;} /* Check number of arguments */ if (nrhs < 2 || nrhs > 3) mexErrMsgTxt("Two or three inputs required."); if (nlhs != 1) mexErrMsgTxt("One output required."); /* Import polygons to structures */ gpc_read_polygon_MATLAB(prhs[0], &subject); gpc_read_polygon_MATLAB(prhs[1], &clip); /* Calling computational routine */ if (nrhs==2 || !mxIsDouble(prhs[2]) || mxGetM(prhs[2])!=1 || mxGetN(prhs[2])!=1) GPC_ARG = GPC_INT; else GPC_ARG = mxGetScalar(prhs[2]); if (GPC_ARG!=GPC_DIFF && GPC_ARG!=GPC_INT && GPC_ARG!=GPC_XOR && GPC_ARG!=GPC_UNION) GPC_ARG = GPC_INT; gpc_polygon_clip(GPC_ARG, &subject, &clip, &result); /* Output Data to Matlab */ dims[0] = 1; dims[1] = result.num_contours; plhs[0] = mxCreateStructArray(2, dims, 3, field_names); gpc_write_polygon_MATLAB(plhs[0], &result); }
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 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; }
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)); }
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; }
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 Polygon2d::substract(Polygon2d &p) { gpc_polygon_clip(GPC_DIFF, &polygon, &p.polygon, &polygon); gpc_free_tristrip(&strip); gpc_polygon_to_tristrip(&polygon,&strip); }
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); }
// 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(int, char**) { AMJU_CALL_STACK; // First poly: a square gpc_vertex v1[5]; // close the poly ? v1[0].x = 1; v1[0].y = 1; v1[1].x = -1; v1[1].y = 1; v1[2].x = -1; v1[2].y = -1; v1[3].x = 1; v1[3].y = -1; v1[4].x = 1; v1[4].y = 1; gpc_vertex_list vl1; vl1.num_vertices = 5; vl1.vertex = v1; gpc_polygon p1; p1.num_contours = 1; p1.contour = &vl1; int h1 = 0; p1.hole = &h1; // Second poly: gpc_vertex v2[5]; v2[0].x = 3; v2[0].y = 1.5; v2[1].x = 0.5; v2[1].y = 1.5; v2[2].x = 0.5; v2[2].y = -0.75; v2[3].x = 3; v2[3].y = -0.75; v2[4].x = 3; v2[4].y = 1.5; gpc_vertex_list vl2; vl2.num_vertices = 5; vl2.vertex = v2; gpc_polygon p2; p2.num_contours = 1; p2.contour = &vl2; int h2 = 0; p2.hole = &h2; // Get intersection gpc_polygon result; gpc_polygon_clip(GPC_INT, &p1, &p2, &result); printf("Contours: %d\n", result.num_contours); for (int i = 0; i < result.num_contours; i++) { printf("Contour %d\n", i); gpc_vertex_list& vlist = result.contour[i]; printf("Vertices: %d\n", vlist.num_vertices); for (int j = 0; j < vlist.num_vertices; j++) { gpc_vertex& v = vlist.vertex[j]; printf("(%f, %f)\n", v.x, v.y); } } return 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); }
void Polygon2d::add(Polygon2d &p) { gpc_polygon_clip(GPC_UNION, &polygon, &p.polygon, &polygon); gpc_free_tristrip(&strip); gpc_polygon_to_tristrip(&polygon,&strip); }