library(sf)
## Linking to GEOS 3.5.0, GDAL 2.1.1, proj.4 4.9.3
library(sfdct)
n <- 150
a <- ct_triangulate(st_as_sf(data.frame(x =  rnorm(n), y = rnorm(n)), coords = c("x", "y")), a = .01)
## all POINT, returning one feature triangulated
n2 <- length(st_geometry(a)[[1]])
b <- st_sf(geometry = st_sfc(unlist(unclass(st_geometry(a)), recursive = FALSE), crs = st_crs(a)),
           b = seq_len(n2))

library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
## balance the n-coodrs, fraction sampled, and the minimum area a = argument to ct_triangulate for
## some wild holy polygons
plot(b %>% sample_frac(0.65) %>% st_union(), col = "grey")

## (beware of the a argument being VERY small, especially if you change units)



## above will always be mostly-convex, so try trimming from the outside in
## rather than randomly throwing triangles away

n <- 400
a <- ct_triangulate(st_as_sf(data.frame(x =  rnorm(n), y = rnorm(n)), coords = c("x", "y")), a = NULL)
## all POINT, returning one feature triangulated
n2 <- length(st_geometry(a)[[1]])
b <- st_sf(geometry = st_sfc(unlist(unclass(st_geometry(a)), recursive = FALSE), crs = st_crs(a)),
           b = seq_len(n2))

plot(b %>% sample_frac(0.65) %>% st_union(), col = "grey")

## hmm, doesn't work
#a %>% mutate(geometry2 = st_cast(geometry, "LINESTRING")) %>% filter(st_length(geometry2) > 1) %>% plot()

## anyway, chew the polygon down via the big edge triangles around the border
poly <- b %>% filter(st_length(st_cast(geometry, "MULTILINESTRING")) < 2)
plot(poly)

## union the triangles to get a valid simple feature
st_union(poly)
## Geometry set for 1 feature 
## geometry type:  POLYGON
## dimension:      XY
## bbox:           xmin: -2.464375 ymin: -2.604462 xmax: 2.883079 ymax: 2.258538
## epsg (SRID):    NA
## proj4string:    NA
## POLYGON((1.23935164570728 -1.44542024954043, 1....