Beispiel #1
0
// 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;
  }
}
Beispiel #2
0
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);
}
Beispiel #3
0
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 );
}
Beispiel #4
0
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);
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #10
0
    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;
    }
Beispiel #11
0
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));
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
0
void Polygon2d::substract(Polygon2d &p)
{
	gpc_polygon_clip(GPC_DIFF, &polygon, &p.polygon, &polygon);
	gpc_free_tristrip(&strip);
	gpc_polygon_to_tristrip(&polygon,&strip);
}
Beispiel #15
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);
}
Beispiel #16
0
// 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);   
     **/ 
    
}
Beispiel #18
0
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;

}
Beispiel #19
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;

}
Beispiel #20
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);

}
Beispiel #21
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);
}