Esempio n. 1
0
SEXP point_in_polygon(SEXP px, SEXP py, SEXP polx, SEXP poly) {
	int i;
	PLOT_POINT p;
	POLYGON pol;
	SEXP ret;

	S_EVALUATOR
	pol.lines = LENGTH(polx); /* check later that first == last */
	pol.p = (PLOT_POINT *) Calloc(pol.lines, PLOT_POINT); /* Calloc does error handling */
	for (i = 0; i < LENGTH(polx); i++) {
		pol.p[i].x = NUMERIC_POINTER(polx)[i];
		pol.p[i].y = NUMERIC_POINTER(poly)[i];
	}
    pol.close = (pol.p[0].x == pol.p[pol.lines - 1].x && 
			pol.p[0].y == pol.p[pol.lines - 1].y);
	setup_poly_minmax(&pol);

	PROTECT(ret = NEW_INTEGER(LENGTH(px)));
	for (i = 0; i < LENGTH(px); i++) {
		p.x = NUMERIC_POINTER(px)[i];
		p.y = NUMERIC_POINTER(py)[i];
		if ((p.x > pol.mbr.min.x) & (p.x <= pol.mbr.max.y) & (p.y > pol.mbr.min.y) & (p.y <= pol.mbr.max.y)) {
			INTEGER_POINTER(ret)[i] = InPoly(p, &pol);
		} else {
			INTEGER_POINTER(ret)[i] = 0;
		}
	}
	Free(pol.p);
	UNPROTECT(1);
	return(ret);
}
Esempio n. 2
0
File: pip.c Progetto: cran/sp
SEXP R_point_in_polygon_sp(const SEXP px, const SEXP py, const SEXP polx, 
		const SEXP poly) {
	int i, pc=0;
	PLOT_POINT p;
	POLYGON pol;
	SEXP ret, px1, py1, polx1, poly1;

	if (MAYBE_REFERENCED(px)) {
		PROTECT(px1 = duplicate(px));
		pc++;
	} else
		px1 = px;
	if (MAYBE_REFERENCED(py)) {
		PROTECT(py1 = duplicate(py));
		pc++;
	} else
		py1 = py;
	if (MAYBE_REFERENCED(polx)) {
		PROTECT(polx1 = duplicate(polx));
		pc++;
	} else
		polx1 = polx;
	if (MAYBE_REFERENCED(poly)) {
		PROTECT(poly1 = duplicate(poly));
		pc++;
	} else
		poly1 = poly;

	pol.lines = LENGTH(polx); /* check later that first == last */
	pol.p = (PLOT_POINT *) R_alloc((size_t) pol.lines, sizeof(PLOT_POINT)); 
	/* transient; will be freed by R; freed by R on user interrupt */
	for (i = 0; i < LENGTH(polx); i++) {
		pol.p[i].x = NUMERIC_POINTER(polx)[i];
		pol.p[i].y = NUMERIC_POINTER(poly)[i];
	}
    pol.close = (pol.p[0].x == pol.p[pol.lines - 1].x && 
			pol.p[0].y == pol.p[pol.lines - 1].y);
	setup_poly_minmax(&pol);

	PROTECT(ret = NEW_INTEGER(LENGTH(px))); pc++;
	for (i = 0; i < LENGTH(px); i++) {
		p.x = NUMERIC_POINTER(px)[i];
		p.y = NUMERIC_POINTER(py)[i];
/*
For each query point q, InPoly returns one of four char's:
	i : q is strictly interior to P
	o : q is strictly exterior to P
	v : q is a vertex of P
	e : q lies on the relative interior of an edge of P
*/
		switch (InPoly(p, &pol)) {
			case 'i': INTEGER_POINTER(ret)[i] = 1; break;
			case 'o': INTEGER_POINTER(ret)[i] = 0; break;
			case 'v': INTEGER_POINTER(ret)[i] = 3; break;
			case 'e': INTEGER_POINTER(ret)[i] = 2; break;
			default: INTEGER_POINTER(ret)[i] = -1; break;
		}
	}
	UNPROTECT(pc);
	return(ret);
}
Esempio n. 3
0
SEXP point_in_polygon2(SEXP px, SEXP py, SEXP polx, SEXP poly, SEXP id, SEXP holes) {
	int i, j;
	PLOT_POINT p;
	POLYGON pol;
	SEXP ret, polxx, polyy;
	int isHole, nHoles, lastPart;
	int *hole, *tmp;
	
	
	PROTECT(px);
	PROTECT(py);
	PROTECT(id = coerceVector(id, INTSXP));
	PROTECT(holes = coerceVector(holes, INTSXP));
	PROTECT(polx = coerceVector(polx, VECSXP));
	PROTECT(poly = coerceVector(poly, VECSXP));
	
	PROTECT(ret = NEW_INTEGER(LENGTH(px)));
	tmp = (int *) malloc(LENGTH(px)*sizeof(double));	
	hole = (int *) malloc(LENGTH(px)*sizeof(int));	
	
	for (i = 0; i < LENGTH(ret); i++) {
		INTEGER_POINTER(ret)[i] = R_NaInt;
		hole[i] = 0;
		tmp[i] = R_NaInt;
	}
	
	lastPart = 0;
	nHoles = 0;
	int oldid = INTEGER_POINTER(id)[0];
	
	int n = LENGTH(polx);
	for (i = 0; i < n; i++) {
		if (i == (n-1) ) {
			lastPart = 1;
		} else if ((INTEGER_POINTER(id)[i+1]) != oldid) {
			lastPart = 1;
			oldid = INTEGER_POINTER(id)[i+1];
		}
		if (INTEGER_POINTER(holes)[i]) {
			isHole = 1;
			nHoles++;
		} else {
			isHole = 0;		
		}
		
		polxx = VECTOR_ELT(polx, i);
		polyy = VECTOR_ELT(poly, i);
		pol.lines = LENGTH(polxx); /* check later that first == last */
		
		pol.p = (PLOT_POINT *) Calloc(pol.lines, PLOT_POINT); /* Calloc does error handling */
		for (j = 0; j < LENGTH(polxx); j++) {
			pol.p[j].x = NUMERIC_POINTER(polxx)[j];
			pol.p[j].y = NUMERIC_POINTER(polyy)[j];
		}
		pol.close = (pol.p[0].x == pol.p[pol.lines - 1].x && pol.p[0].y == pol.p[pol.lines - 1].y);
		// call error if pol.close = FALSE ?

		setup_poly_minmax(&pol);

		if (isHole) {
			for (j = 0; j < LENGTH(px); j++) {
				p.x = NUMERIC_POINTER(px)[j];
				p.y = NUMERIC_POINTER(py)[j];
				if ((p.x > pol.mbr.min.x) & (p.x <= pol.mbr.max.x) & (p.y > pol.mbr.min.y) & (p.y <= pol.mbr.max.y)) {
					if (InPoly(p, &pol)) {
						hole[j] = 1;
					}
				} 
			}
		} else {	
			for (j = 0; j < LENGTH(px); j++) {
				p.x = NUMERIC_POINTER(px)[j];
				p.y = NUMERIC_POINTER(py)[j];
				if ((p.x > pol.mbr.min.x) & (p.x <= pol.mbr.max.x) & (p.y > pol.mbr.min.y) & (p.y <= pol.mbr.max.y)) {
					if (InPoly(p, &pol)) {
						tmp[j] = INTEGER_POINTER(id)[i];
					}
				} 
			}
		}
		Free(pol.p);
		if (lastPart) {
			lastPart = 0;
			if (nHoles > 0) {
				nHoles = 0;
				for (j = 0; j < LENGTH(px); j++) {
					if ((tmp[j] != NA_INTEGER ) & (! hole[j])) {
				//		Rprintf ("%s \n", "a");
						INTEGER_POINTER(ret)[j] = tmp[j];
					}
					tmp[j] = R_NaInt;
					hole[j] = 0;
				}
			} else {
				for (j = 0; j < LENGTH(px); j++) {
					if (NA_INTEGER != tmp[j]) {
						INTEGER_POINTER(ret)[j] = tmp[j];
						tmp[i] = R_NaInt;
					}
				}
			}
		}
		
	}
	
	UNPROTECT(7);
	return(ret);
}