4

This is the code for a rounded square, I wonder if it could get the one for a squircle, which is a very similar figure.

The Wikipedia states that:

Although constructing a rounded square may be conceptually and physically simpler, the squircle has the simpler equation and can be generalised much more easily.

{
  x<-c(1,1,0,0)
  y<-c(1,0,0,1)
  rad <- max(x)/7
  ver<-25

  yMod<-y
  yMod[which(yMod==max(yMod))]<-yMod[which(yMod==max(yMod))]-rad
  yMod[which(yMod==min(yMod))]<-yMod[which(yMod==min(yMod))]+rad

  topline_y<-rep(max(y),2)
  topBotline_x<-c(min(x)+rad, max(x)-rad)
  bottomline_y<-rep(min(y),2)

  pts<- seq(-pi/2, pi*1.5, length.out = ver*4)
  ptsl<-split(pts, sort(rep(1:4, each=length(pts)/4, len=length(pts))) )

  xy_1 <- cbind( (min(x)+rad) + rad * sin(ptsl[[1]]), (max(y)-rad) + rad * cos(ptsl[[1]]))
  xy_2 <- cbind( (max(x)-rad) + rad * sin(ptsl[[2]]), (max(y)-rad) + rad * cos(ptsl[[2]]))
  xy_3 <- cbind( (max(x)-rad) + rad * sin(ptsl[[3]]), (min(y)+rad) + rad * cos(ptsl[[3]]))
  xy_4 <- cbind( (min(x)+rad) + rad * sin(ptsl[[4]]), (min(y)+rad) + rad * cos(ptsl[[4]]))

  newLongx<-c(x[1:2]   ,xy_3[,1],topBotline_x,xy_4[,1], x[3:4],    xy_1[,1],topBotline_x,xy_2[,1])
  newLongy<-c(yMod[1:2],xy_3[,2],bottomline_y,xy_4[,2], yMod[3:4], xy_1[,2],topline_y   ,xy_2[,2])

  par(pty="s")
  plot.new()
  polygon(newLongx,newLongy, col="red")
}

enter image description here

Ferroao
  • 3,042
  • 28
  • 53

2 Answers2

6

Here is a base R squircle function.
I believe the arguments are self descriptive.

  1. x0, y0 - center coordinates.
  2. radius - the squircle radius.
  3. n - number of points to be computed, the default 1000 should make the squircle smooth.
  4. ... - further arguments to be passed to lines. See help('par').

Now for the function and simple tests.

squircle <- function(x0 = 0, y0 = 0, radius, n = 1000, ...){
  r <- function(radius, theta){
    radius/(1 - sin(2*theta)^2/2)^(1/4)
  }
  angle <- seq(0, 2*pi, length.out = n)
  rvec <- r(radius, angle)
  x <- rvec*cos(angle) + x0
  y <- rvec*sin(angle) + y0
  lines(x, y, ...)
}

plot(-5:5, -5:5, type = "n")
squircle(0, 0, 2, col = "red")
squircle(1, 1, 2, col = "blue", lty = "dashed")

enter image description here

Fernandez-Guasti squircle.

This is another type of squircle. The extra argument is s, giving the squareness of the squircle.

# squircleFG: Manuel Fernandez-Guasti  (1992)
squircleFG <- function(x0 = 0, y0 = 0, radius, s, n = 1000, ...){
  angle <- seq(0, 2*pi, length.out = n)
  cosa <- cos(angle)
  sina <- sin(angle)
  sin2a <- sin(2*angle)
  k <- sqrt(1 - sqrt(1 - s^2*sin2a^2))
  x <- k*radius*sign(cosa)/(sqrt(2)*s*abs(sina)) + x0
  y <- k*radius*sign(sina)/(sqrt(2)*s*abs(cosa)) + y0
  lines(x[-n], y[-n], ...)
}


plot(-5:5, -5:5, type = "n")
squircleFG(0, 0, 2, s = 0.75, col = "red")
squircleFG(1, 1, 2, s = 0.75, col = "blue", lty = "dashed")

enter image description here

Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
1

Is the reason to do this yourself, and see if your code can be simplified?

If this is not the case, one possibility is to use the function grid.roundrect from the grid package.

One example adopted from their help page ?grid::grid.roundrect is to simply use

grid.roundrect(width=.5, height=.5, name="rr", gp = gpar(fill = "red"))
Oliver
  • 8,169
  • 3
  • 15
  • 37
  • good, didn't knew. I found not so good to have to write the r (The radius of the rounded corners) in units – Ferroao Jul 27 '19 at 18:12