예제 #1
0
파일: PolyUtil.c 프로젝트: npinto/Polygon
int poly_c_center(gpc_vertex_list *vl, double *cx, double *cy){
  gpc_vertex *v;
  double x=0.0, y=0.0, a;
  int i;
  for (i=0; i < vl->num_vertices-1; i++) {
    v = vl->vertex + i;
    a = v->x * (v+1)->y - (v+1)->x * v->y;
    x += (v->x + (v+1)->x) * a;
    y += (v->y + (v+1)->y) * a;
  }
  if (! poly_c_is_closed(vl)) {
    /* close the loop */
    v = vl->vertex + (vl->num_vertices-1);
    a = v->x * vl->vertex->y - vl->vertex->x * v->y;
    x += (v->x + vl->vertex->x) * a;
    y += (v->y + vl->vertex->y) * a;
  }
  /* this algorithm needs ccw ordered points,
     so we have to calculate the order and multiply,
     what a waste of cpu power... 
     If you know a better way, let me know... */
  a = 6.0*poly_c_area(vl)*poly_c_orientation(vl);
  if (a == 0)
      return 1;
  *cx = x / a;
  *cy = y / a;
  return 0;
}
예제 #2
0
파일: PolyUtil.c 프로젝트: npinto/Polygon
int poly_p_center(gpc_polygon *p, double *cx, double *cy){
  double *x, *y, *a, A=0.0, X=0.0, Y=0.0;
  int i;
  size_t s;
  s = sizeof(double)*p->num_contours;
  a =  (double *)alloca(s);
  x = (double *)alloca(s);
  y = (double *)alloca(s);
  for (i=0; i < p->num_contours; i++) {
    a[i] = ((p->hole[i]) ? -1.0 : 1.0) * poly_c_area(p->contour+i);
    if (poly_c_center(p->contour+i, x+i, y+i) != 0)
        return 1;
  }
  for (i=0; i < p->num_contours; i++)
    A += a[i];
  for (i=0; i < p->num_contours; i++) {
    X += a[i] * x[i];
    Y += a[i] * y[i];
  }
  if (A == 0)
      return 1;
  *cx = X / A;
  *cy = Y / A;
  return 0;
}
예제 #3
0
파일: PolyUtil.c 프로젝트: npinto/Polygon
double poly_p_area(gpc_polygon *p) {
  int i;
  double a = 0.0;
  for (i = 0; i < p->num_contours; i++)
    a += ((p->hole[i]) ? -1.0 : 1.0) * poly_c_area(p->contour+i);
  return a;
}
예제 #4
0
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));
}
예제 #5
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;
}