static PyObject *Polygon_new(PyObject *self, PyObject *args) { PyObject *O = NULL, *TMP = NULL; int hole = 0; Polygon *p = Polygon_NEW(NULL); if (! PyArg_ParseTuple(args, "|Oi", &O, &hole)) Polygon_Raise(ERR_ARG); if (O != NULL) { if ((PyTypeObject *)PyObject_Type(O) == &Polygon_Type) { if (poly_p_clone(((Polygon *)O)->p, p->p) != 0) { Polygon_dealloc(p); return Polygon_Raise(ERR_MEM); } } else if (PyString_Check(O)) { TMP = Polygon_read(p, args); } else if (PySequence_Check(O)) { TMP = Polygon_addContour(p, args); } else if (PyFile_Check(O)) { TMP = Polygon_read(p, args); } else return Polygon_Raise(ERR_ARG); if (TMP) Py_DECREF(TMP); if (PyErr_Occurred()) { Polygon_dealloc(p); return NULL; } } return (PyObject *)p; }
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 Polygon_init(Polygon *self, PyObject *args, PyObject *kwds) { PyObject *O = NULL, *TMP = NULL; int hole; static char *kwlist[] = {"contour", "hole", NULL}; if (! PyArg_ParseTupleAndKeywords(args, kwds, "|Oi", kwlist, &O, &hole)) return -1; if (O != NULL) { if ((PyTypeObject *)PyObject_Type(O) == &Polygon_Type) { if (poly_p_clone(((Polygon *)O)->gpc_p, self->gpc_p) != 0) { Polygon_dealloc(self); Polygon_Raise(ERR_MEM); return -1; } } else if (PyString_Check(O)) { TMP = Polygon_read(self, args); } else if (PySequence_Check(O)) { TMP = Polygon_addContour(self, args); } else if (PyFile_Check(O)) { TMP = Polygon_read(self, args); } else { Polygon_Raise(ERR_ARG); return -1; } if (TMP) { Py_DECREF(TMP); } } return 0; }
static PyObject *Polygon_getitem(PyObject *self, int item) { PyObject *R; gpc_vertex_list * vl = NULL; gpc_vertex *v; int i, imax; gpc_polygon *p = ((Polygon *)self)->p; if (item < 0) item += p->num_contours; if ((item >= p->num_contours) || (item < 0)) return Polygon_Raise(ERR_IND); vl = (p->contour)+item; imax = vl->num_vertices; switch (dataStyle) { case STYLE_TUPLE: { PyObject *XY; v = vl->vertex; R = PyTuple_New(imax); for (i=0; i < imax; i++) { XY = PyTuple_New(2); PyTuple_SetItem(XY, 0, PyFloat_FromDouble(v->x)); PyTuple_SetItem(XY, 1, PyFloat_FromDouble(v->y)); PyTuple_SetItem(R, i, XY); v++; } } break; case STYLE_LIST: { PyObject *XY; v = vl->vertex; R = PyList_New(imax); for (i=0; i < imax; i++) { XY = PyTuple_New(2); PyTuple_SetItem(XY, 0, PyFloat_FromDouble(v->x)); PyTuple_SetItem(XY, 1, PyFloat_FromDouble(v->y)); PyList_SetItem(R, i, XY); v++; } } break; #ifdef WITH_NUMERIC case STYLE_ARRAY: { int dims[2] = {0, 2}; PyArrayObject *a; dims[0] = imax; R = PyArray_FromDims(2, dims, PyArray_DOUBLE); a = (PyArrayObject *)R; memcpy(a->data, vl->vertex, sizeof(gpc_vertex)*vl->num_vertices); } break; #endif /* WITH_NUMERIC */ default: return Polygon_Raise(PolyError, "Unknown data style"); } return Py_BuildValue("O", R); }
static PyObject *Polygon_area(Polygon *self, PyObject *args) { int i=INDEF; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->p->num_contours)) return Py_BuildValue("d", poly_c_area(self->p->contour+i)); else return Polygon_Raise(ERR_IND); } return Py_BuildValue("d", poly_p_area(self->p)); }
static PyObject *Polygon_nPoints(Polygon *self, PyObject *args) { int i=INDEF, n=0; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->p->num_contours)) return Py_BuildValue("i", self->p->contour[i].num_vertices); else return Polygon_Raise(ERR_IND); } for (i=0; i < self->p->num_contours; i++) n += self->p->contour[i].num_vertices; return Py_BuildValue("i", n); }
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); }
static PyObject *Polygon_boundingBox(Polygon *self, PyObject *args) { int i=INDEF; double x0, x1, y0, y1; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->p->num_contours)) poly_c_boundingbox(self->p->contour+i, &x0, &x1, &y0, &y1); else return Polygon_Raise(ERR_IND); } else Polygon_getBoundingBox(self, &x0, &x1, &y0, &y1); return Py_BuildValue("dddd", x0, x1,y0,y1); }
static PyObject *Polygon_aspectRatio(Polygon *self, PyObject *args) { int i=INDEF; double x0, x1, y0, y1; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->gpc_p->num_contours)) poly_c_boundingbox(self->gpc_p->contour+i, &x0, &x1, &y0, &y1); else return Polygon_Raise(ERR_IND); } else Polygon_getBoundingBox(self, &x0, &x1, &y0, &y1); return Py_BuildValue("d", ((x0 != x1) ? fabs((y1-y0)/(x1-x0)) : 0.0)); }
static PyObject *Polygon_orientation(Polygon *self, PyObject *args) { int i=INDEF; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->p->num_contours)) return Py_BuildValue("i", poly_c_orientation(self->p->contour+i)); else return Polygon_Raise(ERR_IND); } else { PyObject *OL; OL = PyTuple_New(self->p->num_contours); for (i = 0; i < self->p->num_contours; i++) PyTuple_SetItem(OL, i, PyFloat_FromDouble(poly_c_orientation(self->p->contour+i))); return Py_BuildValue("O", OL); } }
static PyObject *Polygon_read(Polygon *self, PyObject *args) { PyObject *O; int hflag = 1; if (! PyArg_ParseTuple(args, "O|i", &O, &hflag)) return Polygon_Raise(ERR_ARG); if (PyFile_Check(O)) gpc_read_polygon(PyFile_AsFile(O), hflag, self->gpc_p); else if (PyString_Check(O)) { FILE *f = fopen(PyString_AsString(O), "r"); if (!f) return Polygon_Raise(PyExc_IOError, "Could not open file for reading!"); gpc_read_polygon(f, hflag, self->gpc_p); fclose(f); } else return Polygon_Raise(ERR_ARG); Py_RETURN_NONE; }
static PyObject *Polygon_center(Polygon *self, PyObject *args) { int i=INDEF; double cx, cy; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->p->num_contours)) { if (poly_c_center(self->p->contour+i, &cx, &cy) !=0) return Polygon_Raise(ERR_INV); } else return Polygon_Raise(ERR_IND); } else { if (poly_p_center(self->p, &cx, &cy) != 0) return Polygon_Raise(ERR_INV); } return Py_BuildValue("dd", cx, cy); }
static PyObject *Polygon_isSolid(Polygon *self, PyObject *args) { int i=INDEF; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->p->num_contours)) return Py_BuildValue("i", (self->p->hole[i] > 0) ? 0 : 1); else return Polygon_Raise(ERR_IND); } else { PyObject *O; O = PyTuple_New(self->p->num_contours); for (i = 0; i < self->p->num_contours; i++) PyTuple_SetItem(O, i, PyInt_FromLong((self->p->hole[i] > 0) ? 0 : 1)); return Py_BuildValue("O", O); } }
static PyObject *Polygon_isInside(Polygon *self, PyObject *args) { int i=INDEF, r=0; double x, y; if (! PyArg_ParseTuple(args, "dd|i", &x, &y, &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->p->num_contours)) { if ((r = poly_c_point_inside(self->p->contour+i, x, y)) == -1) return Polygon_Raise(ERR_INV); } else return Polygon_Raise(ERR_IND); } else { if ((r = poly_p_point_inside(self->p, x, y)) == -1) return Polygon_Raise(ERR_INV); } return Py_BuildValue("i", r); }
static PyObject *Polygon_shift(Polygon *self, PyObject *args) { double x, y; if (! PyArg_ParseTuple(args, "dd", &x, &y)) return Polygon_Raise(ERR_ARG); if ((x != 0.0) || (y != 0.0)) poly_p_shift(self->p, x, y); self->bbValid = 0; return Py_BuildValue("O", Py_None); }
static PyObject *Polygon_shift(Polygon *self, PyObject *args) { double x, y; if (! PyArg_ParseTuple(args, "dd", &x, &y)) return Polygon_Raise(ERR_ARG); if ((x != 0.0) || (y != 0.0)) poly_p_shift(self->gpc_p, x, y); self->bbValid = 0; Py_RETURN_NONE; }
static PyObject *Polygon_write(Polygon *self, PyObject *args) { PyObject *O; int hflag = 1; if (! PyArg_ParseTuple(args, "O|i", &O, &hflag)) return Polygon_Raise(ERR_ARG); if (PyFile_Check(O)) gpc_write_polygon(PyFile_AsFile(O), hflag, self->p); else if (PyString_Check(O)) { FILE *f = fopen(PyString_AsString(O), "w"); if (!f) return Polygon_Raise(PyExc_IOError, "Could not open file for writing!"); gpc_write_polygon(f, hflag, self->p); fclose(f); } else return Polygon_Raise(ERR_ARG); Py_INCREF(Py_None); return Py_None; }
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 * setEpsilon(PyObject *self, PyObject *arg) { if (PyFloat_Check(arg)) GPC_EPSILON = PyFloat_AsDouble(arg); else if (PyInt_Check(arg)) GPC_EPSILON = PyInt_AsLong(arg); else if (PyLong_Check(arg)) GPC_EPSILON = PyLong_AsLong(arg); else return Polygon_Raise(ERR_ARG); return Py_BuildValue("O", Py_None); }
static PyObject *Polygon_warpToBox(Polygon *self, PyObject *args) { double x0, x1, y0, y1; if (! PyArg_ParseTuple(args, "dddd", &x0, &x1, &y0, &y1)) return Polygon_Raise(ERR_ARG); if (self->bbValid) poly_p_warpToBox(self->p, x0, x1, y0, y1, self->boundingBox); else poly_p_warpToBox(self->p, x0, x1, y0, y1, NULL); self->bbValid = 0; return Py_BuildValue("O", Py_None); }
static PyObject *Polygon_isSolid(Polygon *self, PyObject *args) { int i=INDEF; if (! PyArg_ParseTuple(args, "|i", &i)) return Polygon_Raise(ERR_ARG); if (i!=INDEF) { if ((i >= 0) && (i < self->gpc_p->num_contours)) if (self->gpc_p->hole[i] > 0) Py_RETURN_FALSE; else Py_RETURN_TRUE; else return Polygon_Raise(ERR_IND); } else { PyObject *O; O = PyTuple_New(self->gpc_p->num_contours); for (i = 0; i < self->gpc_p->num_contours; i++) PyTuple_SetItem(O, i, PyBool_FromLong((self->gpc_p->hole[i] > 0) ? 0 : 1)); return O; } }
static PyObject *Polygon_warpToBox(Polygon *self, PyObject *args) { double x0, x1, y0, y1; if (! PyArg_ParseTuple(args, "dddd", &x0, &x1, &y0, &y1)) return Polygon_Raise(ERR_ARG); if (self->bbValid) poly_p_warpToBox(self->gpc_p, x0, x1, y0, y1, self->boundingBox); else poly_p_warpToBox(self->gpc_p, x0, x1, y0, y1, NULL); self->bbValid = 0; Py_RETURN_NONE; }
static PyObject * setEpsilon(PyObject *self, PyObject *arg) { if (PyFloat_Check(arg)) GPC_EPSILON = PyFloat_AsDouble(arg); else if (PyInt_Check(arg)) GPC_EPSILON = PyInt_AsLong(arg); else if (PyLong_Check(arg)) GPC_EPSILON = PyLong_AsLong(arg); else return Polygon_Raise(ERR_ARG); Py_RETURN_NONE; }
static PyObject *Polygon_addContour(Polygon *self, PyObject *args) { #ifdef WITH_NUMERIC PyObject *a=NULL; gpc_vertex_list *vl; int hole = 0; if (! PyArg_ParseTuple(args, "O|i", &a, &hole)) return Polygon_Raise(ERR_ARG); if ((a = PyArray_ContiguousFromObject(a, PyArray_DOUBLE, 2, 2)) == NULL) return Polygon_Raise(ERR_ARG); if (((PyArrayObject *)a)->nd != 2) return Polygon_Raise(ERR_ARG); if (((PyArrayObject *)a)->dimensions[1] != 2) return Polygon_Raise(ERR_ARG); vl = PyMem_New(gpc_vertex_list, 1); vl->num_vertices = ((PyArrayObject *)a)->dimensions[0]; vl->vertex = PyMem_New(gpc_vertex, vl->num_vertices); memcpy((vl->vertex), (((PyArrayObject *)a)->data), 2*vl->num_vertices*sizeof(double)); Py_DECREF(a); #else PyObject *list=NULL, *flist, *point=NULL, *X, *Y; gpc_vertex_list *vl; gpc_vertex *v; int i, imax, hole = 0; if (! PyArg_ParseTuple(args, "O|i", &list, &hole)) return Polygon_Raise(ERR_ARG); if (! PySequence_Check(list)) return Polygon_Raise(ERR_ARG); flist = PySequence_Fast(list, "this is not a sequence"); if ((! flist) || ((imax = PySequence_Length(flist)) <= 2)) return Polygon_Raise(ERR_INV); vl = PyMem_New(gpc_vertex_list, 1); vl->num_vertices = imax; vl->vertex = v = PyMem_New(gpc_vertex, imax); for (i=0; i<imax; i++) { point = PySequence_Fast(PySequence_Fast_GET_ITEM(flist, i), "this is not a point"); if ((!point) || (PySequence_Length(point) != 2)) return Polygon_Raise(ERR_INV); v->x = PyFloat_AsDouble(X = PyNumber_Float(PySequence_Fast_GET_ITEM(point, 0))); v->y = PyFloat_AsDouble(Y = PyNumber_Float(PySequence_Fast_GET_ITEM(point, 1))); v++; Py_DECREF(X); Py_DECREF(Y); Py_DECREF(point); } Py_DECREF(flist); #endif /* WITH_NUMERIC */ gpc_add_contour(self->p, vl, hole); self->bbValid = 0; PyMem_Free(vl->vertex); PyMem_Free(vl); Py_INCREF(Py_None); return Py_None; }
/* make a new Polygon, using gpc_p if not NULL */ static Polygon *Polygon_NEW(gpc_polygon *gpc_p) { Polygon *obj = PyObject_NEW(Polygon, &Polygon_Type); if (gpc_p != NULL) obj->gpc_p = gpc_p; else { if (! (obj->gpc_p = poly_p_new())) return (Polygon *)Polygon_Raise(ERR_MEM); } obj->bbValid = 0; obj->attr = NULL; return obj; }
static PyObject *Polygon_flip(Polygon *self, PyObject *args) { double x = DNDEF; if (! PyArg_ParseTuple(args, "|d", &x)) return Polygon_Raise(ERR_ARG); if (x == DNDEF) { double x0, x1, y0, y1; Polygon_getBoundingBox(self, &x0, &x1, &y0, &y1); x = 0.5 * (x0+x1); } else self->bbValid = 0; poly_p_flip(self->gpc_p, x); Py_RETURN_NONE; }
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; }
static PyObject *Polygon_flop(Polygon *self, PyObject *args) { double y = DNDEF; if (! PyArg_ParseTuple(args, "|d", &y)) return Polygon_Raise(ERR_ARG); if (y == DNDEF) { double x0, x1, y0, y1; Polygon_getBoundingBox(self, &x0, &x1, &y0, &y1); y = 0.5 * (y0+y1); } else self->bbValid = 0; poly_p_flop(self->p, y); return Py_BuildValue("O", Py_None); }
static Polygon *Polygon_NEW(void *ptr) { Polygon *obj = PyObject_NEW(Polygon, &Polygon_Type); if (ptr != NULL) /* create from existing gpc_polygon struct */ obj->p = (gpc_polygon *)ptr; else { /* create a new struct */ if (! (obj->p = poly_p_new())) return (Polygon *)Polygon_Raise(ERR_MEM); } obj->bbValid = 0; obj->attr = NULL; return obj; }
static PyObject *Polygon_cloneContour(Polygon *self, PyObject *args) { int con, i, hole=-1; double xs=1.0, ys=1.0; gpc_vertex_list *vl = NULL, *vlnew = NULL; gpc_polygon *p = ((Polygon *)self)->gpc_p; if (! PyArg_ParseTuple(args, "i|ddi", &con, &xs, &ys, &hole)) return Polygon_Raise(ERR_ARG); if (con < 0) con += p->num_contours; if ((con >= p->num_contours) || (con < 0)) return Polygon_Raise(ERR_IND); vl = (p->contour)+con; vlnew = PyMem_New(gpc_vertex_list, 1); vlnew->num_vertices = vl->num_vertices; vlnew->vertex = PyMem_New(gpc_vertex, vlnew->num_vertices); for (i=0; i < vl->num_vertices; i++) { vlnew->vertex[i].x = vl->vertex[i].x + xs; vlnew->vertex[i].y = vl->vertex[i].y + ys; } gpc_add_contour(p, vlnew, p->hole[con]); self->bbValid = 0; PyMem_Free(vlnew->vertex); PyMem_Free(vlnew); return Py_BuildValue("i", (p->num_contours)-1); }