# vertices
<- sqrt((5-sqrt(5))/10) # outer circumradius
R <- sqrt((25-11*sqrt(5))/10) # circumradius of the inner pentagon
r <- R * vapply(0L:4L, function(i) cos(pi/180 * (90+72*i)), numeric(1L))
X <- R * vapply(0L:4L, function(i) sin(pi/180 * (90+72*i)), numeric(1L))
Y <- r * vapply(0L:4L, function(i) cos(pi/180 * (126+72*i)), numeric(1L))
x <- r * vapply(0L:4L, function(i) sin(pi/180 * (126+72*i)), numeric(1L))
y <- rbind(
vertices c(X[1L], Y[1L]),
c(x[1L], y[1L]),
c(X[2L], Y[2L]),
c(x[2L], y[2L]),
c(X[3L], Y[3L]),
c(x[3L], y[3L]),
c(X[4L], Y[4L]),
c(x[4L], y[4L]),
c(X[5L], Y[5L]),
c(x[5L], y[5L])
)
# edge indices (pairs)
<- cbind(1L:10L, c(2L:10L, 1L)) edges
# constrained Delaunay triangulation
library(RCDT)
<- delaunay(vertices, edges) del
# plot
<- par(mar = c(0, 0, 0, 0))
opar plotDelaunay(
type = "n", asp = 1, fillcolor = "distinct", lwd_borders = 3,
del, xlab = NA, ylab = NA, axes = FALSE
)par(opar)
# area
delaunayArea(del)
## [1] 0.3102707
sqrt(650 - 290*sqrt(5)) / 4 # exact value
## [1] 0.3102707
I found its vertices with the Julia library Luxor.
<- rbind(
vertices c(2.121320343559643, 2.1213203435596424),
c(0.5740251485476348, 1.38581929876693),
c(0.0, 3.0),
c(-0.5740251485476346, 1.38581929876693),
c(-2.1213203435596424, 2.121320343559643),
c(-1.38581929876693, 0.5740251485476349),
c(-3.0, 0.0),
c(-1.3858192987669302, -0.5740251485476345),
c(-2.121320343559643, -2.1213203435596424),
c(-0.5740251485476355, -1.3858192987669298),
c(0.0, -3.0),
c(0.574025148547635, -1.38581929876693),
c(2.121320343559642, -2.121320343559643),
c(1.3858192987669298, -0.5740251485476355),
c(3.0, 0.0),
c(1.38581929876693, 0.5740251485476349)
)
# edge indices
<- cbind(1L:16L, c(2L:16L, 1L)) edges
library(RCDT)
<- delaunay(vertices, edges) del
<- par(mar = c(0, 0, 0, 0))
opar plotDelaunay(
type = "n", asp = 1, fillcolor = "distinct",
del, col_borders = "navy", lty_edges = 2, lwd_borders = 3, lwd_edges = 2,
xlab = NA, ylab = NA, axes = FALSE
)par(opar)
<- 100L # outer number of sides
n <- seq(0, 2*pi, length.out = n + 1L)[-1L]
angles1 <- cbind(cos(angles1), sin(angles1))
outer_points <- 10L # inner number of sides
m <- seq(0, 2*pi, length.out = m + 1L)[-1L]
angles2 <- 0.5 * cbind(cos(angles2), sin(angles2))
inner_points <- rbind(outer_points, inner_points)
points # constraint edges
<- 1L:n
indices <- cbind(
edges_outer c(indices[-1L], indices[1L])
indices,
)<- n + 1L:m
indices <- cbind(
edges_inner c(indices[-1L], indices[1L])
indices,
)<- rbind(edges_outer, edges_inner)
edges # constrained Delaunay triangulation
<- delaunay(points, edges) del
# plot
<- par(mar = c(0, 0, 0, 0))
opar plotDelaunay(
type = "n", asp = 1, lwd_borders = 3, col_borders = "black",
del, fillcolor = "random", col_edges = "yellow",
axes = FALSE, xlab = NA, ylab = NA
)par(opar)
One can also enter a vector of colors in the fillcolor
argument. First, see the number of triangles:
"mesh"]]
del[[## mesh3d object with 110 vertices, 110 triangles.
There are 110 triangles. Let’s make a cyclic vector of 110 colors:
<- viridisLite::viridis(55)
colors <- c(colors, rev(colors)) colors
And let’s plot now:
<- par(mar = c(0, 0, 0, 0))
opar plotDelaunay(
type = "n", asp = 1, lwd_borders = 3, col_borders = "black",
del, fillcolor = colors, col_edges = "black", lwd_edges = 1.5,
axes = FALSE, xlab = NA, ylab = NA
)par(opar)
The colors are assigned to the triangles in the order they are given, but only after the triangles have been circularly ordered.
I found this curve here.
<- seq(-pi, pi, length.out = 193L)[-1L]
t_ <- 0.1 + 5*sqrt(cos(6*t_)^2 + 0.7^2)
r_ <- cbind(r_*cos(t_), r_*sin(t_))
xy <- cbind(1L:192L, c(2L:192L, 1L))
edges1 <- which(r_ == min(r_))
inner <- cbind(inner, c(tail(inner, -1L), inner[1L]))
edges2 <- delaunay(xy, edges = rbind(edges1, edges2)) del
<- par(mar = c(0, 0, 0, 0))
opar plotDelaunay(
type = "n", col_borders = "black", lwd_borders = 2,
del, fillcolor = "random", col_edges = "white",
axes = FALSE, xlab = NA, ylab = NA, asp = 1
)polygon(xy[inner, ], col = "#ffff99")
par(opar)
The ‘RCDT’ package as a whole is distributed under GPL-3 (GNU GENERAL PUBLIC LICENSE version 3).
It uses the C++ library CDT which is permissively licensed under MPL-2.0. A copy of the ‘CDT’ license is provided in the file LICENSE.note, and the source code of this library can be found in the src folder.