如何在R语言中绘制一个圆角正方形(squircle)

4
这是一个圆角正方形的代码,我想知道是否能够得到一个类似的图形——squircle(四分之一圆形)。
维基百科上说:
尽管构造圆角正方形在概念上和物理上可能更简单,但squircle有较简单的方程,并且可以更轻松地进行推广。
{
  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

2个回答

6
这是一个基本的R squircle函数。
我相信这些参数都很容易理解:

  1. x0y0 - 中心坐标。
  2. radius - squircle半径。
  3. n - 要计算的点数,默认值为1000,可以使squircle更加平滑。
  4. ... - 传递给lines的其他参数。请参见help('par')

现在是函数和简单测试。

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

费尔南德斯-瓜斯蒂平方圆。

这是另一种类型的平方圆。额外的参数是s,表示平方圆的方正度

# 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


@Ferroao 如果您修改指数,它将不再是一个squircle,但仍然是一个superellipse - Rui Barradas

1

你这么做的原因是想看看自己的代码是否可以简化吗?

如果不是这种情况,一种可能性是使用 grid 包中的 grid.roundrect 函数。

他们帮助页面 ?grid::grid.roundrect 中采用的一个示例是简单地使用:

grid.roundrect(width=.5, height=.5, name="rr", gp = gpar(fill = "red"))

好的,我不知道。我觉得写圆角的半径时必须使用单位不太好。 - Ferroao

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接