void Polygon2d::addHole(std::vector<std::pair<double,double>> vec) { gpc_vertex_list list={static_cast<int>(vec.size()),reinterpret_cast<gpc_vertex*>(&vec[0])}; gpc_add_contour(&polygon,&list,1); gpc_free_tristrip(&strip); gpc_polygon_to_tristrip(&polygon,&strip); }
// ============================================================================ /// Converts polygon into set of triangles. QList<QPolygonF> triangulatePolygon( const QPolygonF& polygon ) { QList<QPolygonF> triangles; if ( polygon.size() < 3 ) { qDebug("Can't create shape from polygon with less than 3 vertices!"); return triangles; } if ( polygon.size() == 3 ) { triangles.append( polygon ); return triangles; } //qDebug("Triangulating polygon with %d vertices", polygon.size() ); // triangulate here // create GPC polygon from QPolygonF gpc_vertex_list vertexList; gpc_polygon gpcpolygon; vertexList.num_vertices = polygon.size(); vertexList.vertex = new gpc_vertex[ polygon.size() ]; for( int i = 0; i < vertexList.num_vertices; i++ ) { vertexList.vertex[i].x = polygon[i].x(); vertexList.vertex[i].y = polygon[i].y(); } gpcpolygon.num_contours = 1; gpcpolygon.hole = NULL; gpcpolygon.contour = &vertexList; // request triangles gpc_tristrip tristrip; gpc_polygon_to_tristrip( &gpcpolygon, &tristrip ); // create triangles from tristrups for( int s = 0; s < tristrip.num_strips; s++ ) { gpc_vertex_list& strip = tristrip.strip[s]; int numTriangles = strip.num_vertices - 2; for ( int t = 0; t < numTriangles; t++ ) { QPolygonF triangle; triangle.append( QPointF( strip.vertex[t].x, strip.vertex[t].y ) ); triangle.append( QPointF( strip.vertex[t+1].x, strip.vertex[t+1].y ) ); triangle.append( QPointF( strip.vertex[t+2].x, strip.vertex[t+2].y ) ); triangles.append( triangle ); } } // release polygon delete[] vertexList.vertex; gpc_free_tristrip( &tristrip ); //qDebug("%d triangles created", triangles.size() ); return triangles; }
// 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 }
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); }
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); }
static PyObject *Polygon_triStrip(Polygon *self) { gpc_tristrip *t = (gpc_tristrip *)alloca(sizeof(gpc_tristrip)); gpc_vertex_list *vl; PyObject *R, *TS; int i, j; t->num_strips = 0; t->strip = NULL; gpc_polygon_to_tristrip(self->p, t); switch (dataStyle) { case STYLE_TUPLE: { PyObject *P; gpc_vertex *v; R = PyTuple_New(t->num_strips); for (i=0; i < t->num_strips; i++) { vl = t->strip + i; v = vl->vertex; TS = PyTuple_New(vl->num_vertices); for (j=0; j < vl->num_vertices; j++) { P = PyTuple_New(2); PyTuple_SetItem(P, 0, PyFloat_FromDouble(v->x)); PyTuple_SetItem(P, 1, PyFloat_FromDouble(v->y)); PyTuple_SetItem(TS, j, P); v++; } PyTuple_SetItem(R, i, TS); } } break; case STYLE_LIST: { PyObject *P; gpc_vertex *v; R = PyList_New(t->num_strips); for (i=0; i < t->num_strips; i++) { vl = t->strip + i; v = vl->vertex; TS = PyList_New(vl->num_vertices); for (j=0; j < vl->num_vertices; j++) { P = PyTuple_New(2); PyTuple_SetItem(P, 0, PyFloat_FromDouble(v->x)); PyTuple_SetItem(P, 1, PyFloat_FromDouble(v->y)); PyList_SetItem(TS, j, P); v++; } PyList_SetItem(R, i, TS); } } break; #ifdef WITH_NUMERIC case STYLE_ARRAY: { int dims[2] = {0, 2}; R = PyTuple_New(t->num_strips); for (i=0; i < t->num_strips; i++) { vl = t->strip + i; dims[0] = vl->num_vertices; TS = PyArray_FromDims(2, dims, PyArray_DOUBLE); memcpy(((PyArrayObject *)TS)->data, vl->vertex, sizeof(gpc_vertex)*vl->num_vertices); PyTuple_SetItem(R, i, (PyObject *)TS); } } break; #endif /* WITH_NUMERIC */ default: return Polygon_Raise(PolyError, "Unknown data style"); } gpc_free_tristrip(t); return Py_BuildValue("O", R); }
static PyObject *Polygon_sample(Polygon *self, PyObject *args) { PyObject *rng, *val1, *val2, *val3, *res; double A; if (! PyArg_ParseTuple(args, "O", &rng)) return Polygon_Raise(ERR_ARG); if (!PyCallable_Check(rng)) return Polygon_Raise(ERR_ARG); res = NULL; Py_INCREF(rng); // Sampling requires three random values val1 = val2 = val3 = NULL; val1 = PyObject_CallObject(rng, NULL); val2 = PyObject_CallObject(rng, NULL); val3 = PyObject_CallObject(rng, NULL); Py_DECREF(rng); if ((! PyFloat_Check(val1)) || (! PyFloat_Check(val2)) || (! PyFloat_Check(val3))) { Polygon_Raise(PolyError, "rng returned something other than a float"); goto cleanup; } A = poly_p_area(self->gpc_p); if (A == 0.0) { Polygon_Raise(PolyError, "cannot sample from a zero-area polygon"); goto cleanup; } else { gpc_tristrip *t = (gpc_tristrip *)alloca(sizeof(gpc_tristrip)); gpc_vertex_list *vl; gpc_vertex_list one_tri; int i, j; gpc_vertex *tri_verts; double a, b, c, px, py; t->num_strips = 0; t->strip = NULL; gpc_polygon_to_tristrip(self->gpc_p, t); A *= PyFloat_AS_DOUBLE(val1); one_tri.num_vertices = 3; for (i=0; i < t->num_strips; i++) { vl = t->strip + i; for (j=0; j < vl->num_vertices - 2; j++) { one_tri.vertex = vl->vertex + j; A -= poly_c_area(& one_tri); if (A <= 0.0) goto tri_found; } } tri_found: // sample a point from this triangle a = PyFloat_AS_DOUBLE(val2); b = PyFloat_AS_DOUBLE(val3); if ((a + b) > 1.0) { a = 1 - a; b = 1 - b; } c = 1 - a - b; tri_verts = one_tri.vertex; px = a * tri_verts[0].x + b * tri_verts[1].x + c * tri_verts[2].x; py = a * tri_verts[0].y + b * tri_verts[1].y + c * tri_verts[2].y; res = PyTuple_New(2); PyTuple_SetItem(res, 0, PyFloat_FromDouble(px)); PyTuple_SetItem(res, 1, PyFloat_FromDouble(py)); gpc_free_tristrip(t); } cleanup: Py_XDECREF(val1); Py_XDECREF(val2); Py_XDECREF(val3); return res; }
void Polygon2d::add(Polygon2d &p) { gpc_polygon_clip(GPC_UNION, &polygon, &p.polygon, &polygon); gpc_free_tristrip(&strip); gpc_polygon_to_tristrip(&polygon,&strip); }
void Polygon2d::substract(Polygon2d &p) { gpc_polygon_clip(GPC_DIFF, &polygon, &p.polygon, &polygon); gpc_free_tristrip(&strip); gpc_polygon_to_tristrip(&polygon,&strip); }
Polygon2d::~Polygon2d() { gpc_free_tristrip(&strip); gpc_free_polygon(&polygon); }