Example #1
0
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);
}
Example #2
0
// ============================================================================
/// 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;
}
Example #3
0
File: lgpc.c Project: LuaDist/lgpc
static int Lstrip(lua_State *L)			/** strip(p) */
{
 gpc_tristrip s;
 gpc_polygon *p=Pget(L,1);
 gpc_polygon *r=Pnew(L);
 gpc_polygon_to_tristrip(p,&s);
 r->num_contours=s.num_strips;
 r->contour=s.strip;
 return 1;
}
Example #4
0
// load a level in memory
bool GameDataOpenLevel(const char *chFileName)
{
	FILE	*pFile;

	// close previous level
	GameDataEndLevel();

	if ((pFile = fopen(chFileName, "r")) != NULL)
	{
		gpc_read_polygon(pFile, 0, &oPolyLevel);
#ifdef EX0_CLIENT
		gpc_polygon_to_tristrip(&oPolyLevel, &oTristripLevel);
#endif // EX0_CLIENT
		fclose(pFile);
	}
	else
	{
		// level not found
		string sMessage = (string)"an eX0 level file \'" + chFileName + "\' could not be opened.";
#ifdef WIN32
		// TODO: Refactor, put error messages in the right place (outside?)
		//MessageBox(NULL, sMessage.c_str(), "eX0 error", MB_ICONERROR);
#else
		//printf("%s\n", sMessage.c_str());
#endif
		printf("%s (errno=%d)\n", sMessage.c_str(), errno);
		return false;
	}

#ifdef EX0_CLIENT
	// DEBUG: Open the same level with PolyBoolean
	LoadParea2(chFileName, &pPolyBooleanLevel);
	if (pPolyBooleanLevel == NULL)
		{ printf("Failed to load the PolyBoolean level.\n"); Terminate(2); }
	if (PAREA::Triangulate(pPolyBooleanLevel) != 0)
		{ printf("PolyBoolean level triangulation failed.\n"); Terminate(3); }

	// DEBUG: Print info about the level, namely the tristrip vertex count
	printf("opened level %s\n", chFileName);
	int nTotalTriangles = 0, nTotalVertices = 0;
	for (int nLoop1 = 0; nLoop1 < oTristripLevel.num_strips; ++nLoop1) {
		nTotalVertices += oTristripLevel.strip[nLoop1].num_vertices;
		nTotalTriangles += oTristripLevel.strip[nLoop1].num_vertices - 2;
	}
	printf("gpc tri: triangle count = %d; vertex count = %d; tristrips = %d\n", nTotalTriangles, nTotalVertices, oTristripLevel.num_strips);
	printf("PB tri: triangle count = %d; vertex count = %d\n", pPolyBooleanLevel->tnum, 3 * pPolyBooleanLevel->tnum);
#endif // EX0_CLIENT

	return true;
}
Example #5
0
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);
}
Example #6
0
File: Rgpc.c Project: cran/gpclib
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);
  
}
Example #7
0
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);
}
Example #8
0
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;
}
Example #9
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);
}
Example #10
0
Polygon2d::Polygon2d(std::vector<std::pair<double,double>> &verts):polygon{0,0,0},strip{0,0}
{
	gpc_vertex_list list={static_cast<int>(verts.size()),reinterpret_cast<gpc_vertex*>(&verts[0])};
	gpc_add_contour(&polygon,&list,0);
	gpc_polygon_to_tristrip(&polygon,&strip);
}
Example #11
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);
}