From 81118f83d4b11bd850b8ba4b60d33d1aa1f015a8 Mon Sep 17 00:00:00 2001
From: Philippe Verley <philippe.verley@ird.fr>
Date: Tue, 23 Aug 2016 15:39:54 +0000
Subject: [PATCH] Fixed a bug in the triangulate function when the outer
 polygon has only four vertices and no hole

---
 R/triangulate.R | 95 +++++++++++++++++++++++++++----------------------
 1 file changed, 53 insertions(+), 42 deletions(-)

diff --git a/R/triangulate.R b/R/triangulate.R
index fb42576..5b05a24 100755
--- a/R/triangulate.R
+++ b/R/triangulate.R
@@ -1,42 +1,53 @@
-triangulate<-function(outer.poly,holes) {
-	if(is.vector(outer.poly)&&is.numeric(outer.poly)&&(length(outer.poly)==4)) {
-		stopifnot((outer.poly[3]-outer.poly[1])>0)
-		stopifnot((outer.poly[4]-outer.poly[2])>0)
-		outer.poly<-list(x=c(outer.poly[1],outer.poly[1],outer.poly[3],outer.poly[3]),
-		y=c(outer.poly[2],outer.poly[4],outer.poly[4],outer.poly[2]))
-	}
-	if(!missing(holes)) {
-		if(is.list(holes[[1]])) {
-			if(all(unlist(lapply(holes,is.poly))))
-				stopifnot(!overlapping.polygons(holes))
-		}
-		else if(is.poly(holes))
-			holes<-list(holes)
-		for(i in 1:length(holes))
-			stopifnot(in.poly(holes[[i]]$x,holes[[i]]$y,outer.poly))
-		nbpoly<-length(holes)+1
-		nbpts<-length(outer.poly$x)
-		vertX<-outer.poly$x
-		vertY<-outer.poly$y
-		for(i in 2:nbpoly) {
-			nbpts[i]<-length(holes[[i-1]]$x)
-			vertX<-c(vertX,holes[[i-1]]$x)
-			vertY<-c(vertY,holes[[i-1]]$y)
-		}
-		nbptot<-sum(nbpts)
-		nbtri<-(nbptot-2)+2*(nbpoly-1)
-	}
-	else {
-		nbpoly<-1
-		nbpts<-nbptot<-length(outer.poly$x)
-		vertX<-outer.poly$x
-		vertY<-outer.poly$y
-		nbtri<-(nbpts-2)
-	}
-	tri<-.C("triangulate",
-		as.integer(nbpoly),as.integer(nbpts),as.integer(nbptot),as.double(vertX),as.double(vertY),as.integer(nbtri),
-		X1=double(nbtri),Y1=double(nbtri),X2=double(nbtri),Y2=double(nbtri),X3=double(nbtri),Y3=double(nbtri),
-		PACKAGE="ads")
-	return(data.frame(ax=tri$X1,ay=tri$Y1,bx=tri$X2,by=tri$Y2,cx=tri$X3,cy=tri$Y3))
-}
-
+triangulate<-function(outer.poly,holes) {
+	if(is.vector(outer.poly)&&is.numeric(outer.poly)&&(length(outer.poly)==4)) {
+		stopifnot((outer.poly[3]-outer.poly[1])>0)
+		stopifnot((outer.poly[4]-outer.poly[2])>0)
+		outer.poly<-list(x=c(outer.poly[1],outer.poly[1],outer.poly[3],outer.poly[3]),
+		y=c(outer.poly[2],outer.poly[4],outer.poly[4],outer.poly[2]))
+	}
+	if(!missing(holes)) {
+		if(is.list(holes[[1]])) {
+			if(all(unlist(lapply(holes,is.poly))))
+				stopifnot(!overlapping.polygons(holes))
+		}
+		else if(is.poly(holes))
+			holes<-list(holes)
+		for(i in 1:length(holes))
+			stopifnot(in.poly(holes[[i]]$x,holes[[i]]$y,outer.poly))
+		nbpoly<-length(holes)+1
+		nbpts<-length(outer.poly$x)
+		vertX<-outer.poly$x
+		vertY<-outer.poly$y
+		for(i in 2:nbpoly) {
+			nbpts[i]<-length(holes[[i-1]]$x)
+			vertX<-c(vertX,holes[[i-1]]$x)
+			vertY<-c(vertY,holes[[i-1]]$y)
+		}
+		nbptot<-sum(nbpts)
+		nbtri<-(nbptot-2)+2*(nbpoly-1)
+	}
+	else {
+		# phv 20160823 bug fix: triangulate C function crashes with 4 points polygons and no hole
+		# Bypass the C function and returns 2 triangles made respectively of vertices (1, 2, 3) and (1, 3, 4)
+		if(nrow(outer.poly)==4) {
+			return(data.frame(
+				ax=c(outer.poly$x[1], outer.poly$x[1]),
+				ay=c(outer.poly$y[1], outer.poly$y[1]),
+				bx=c(outer.poly$x[2], outer.poly$x[3]),
+				by=c(outer.poly$y[2], outer.poly$y[3]),
+				cx=c(outer.poly$x[3], outer.poly$x[4]),
+				cy=c(outer.poly$y[3], outer.poly$y[4])))
+		}  
+		nbpoly<-1
+		nbpts<-nbptot<-length(outer.poly$x)
+		vertX<-outer.poly$x
+		vertY<-outer.poly$y
+		nbtri<-(nbpts-2)
+	}
+	tri<-.C("triangulate",
+		as.integer(nbpoly),as.integer(nbpts),as.integer(nbptot),as.double(vertX),as.double(vertY),as.integer(nbtri),
+		X1=double(nbtri),Y1=double(nbtri),X2=double(nbtri),Y2=double(nbtri),X3=double(nbtri),Y3=double(nbtri),
+		PACKAGE="ads")
+	return(data.frame(ax=tri$X1,ay=tri$Y1,bx=tri$X2,by=tri$Y2,cx=tri$X3,cy=tri$Y3))
+}
+
-- 
GitLab