Constructing the tangents isn't too hard, using the ellipse formula given in this answer. It gives the ellipse in parametric form; to get the slopes of the tangents, use (dy/dtheta)/(dx/dtheta)
, i.e.
slopes <- (-a * sin(theta) * sin(angle) + b * cos(theta) * cos(angle))/
(-a * sin(theta) * cos(angle) - b * cos(theta) * sin(angle))
Then the intercepts come from intercepts <- y - slopes*x
, where x
and y
are from points on the ellipse.
Finally, you would intersect successive pairs of those tangent lines to get the vertices of the outer polygon. Here's a complete solution:
innerouter <- function(x0, y0, a, b, angle, n = 360) {
angle <- angle/360 * 2 * pi
theta <- c(seq(0, 2 * pi, length.out = n), 0)
slopes <- (-a * sin(theta) * sin(angle) + b * cos(theta) * cos(angle))/
(-a * sin(theta) * cos(angle) - b * cos(theta) * sin(angle))
crds <- cbind(a * cos(theta) * cos(angle) - b * sin(theta) * sin(angle) + x0,
a * cos(theta) * sin(angle) + b * sin(theta) * cos(angle) + y0)
intercepts <- crds[,2] - slopes*crds[,1]
i <- 1:(n-1)
x <- (intercepts[i] - intercepts[i+1])/(slopes[i+1] - slopes[i])
y <- slopes[i]*x + intercepts[i]
outer <- cbind(c(x, x[1]), c(y, y[1]))
inner <- crds
list(inner = inner, outer = outer)
}
both <- innerouter(0,0,5, 10, 45, n=10)
plot(both$outer, col = "green", type = "l")
lines(both$inner, col = "red")

Created on 2023-05-10 with reprex v2.0.2