使用R在四边形周围绘制一个最小半径的圆

时间:2016-04-26 07:21:16

标签: r

让我们考虑一个带顶点的四边形

       x            y
1   0.0057      -0.0249
2   0.0209       0.0028
3  -0.0058       0.0250
4  -0.0209      -0.0028.

如果R中有任何包裹或代码可以找到并在上面的四边形周围画出最小半径的圆圈,请有人建议我。感谢。

2 个答案:

答案 0 :(得分:1)

我不知道任何可以从头开始解决问题的库,但其中一种方法可能是

  • 确定最小半径(取决于你所拥有的cuadrilateral类型,即方形或矩形)

  • 按照here

  • 的说明使用draw.circle库中的plotrix

<强>更新 在这个特定的例子中,四边形看起来像这样: enter image description here

使用

ggplot(rectangle,aes(x=x,y=y)) + geom_polygon(aes(x=x,y=y), colour="black", fill = NA)

其中矩形是

rectangle = data.frame("x"=c(0.0057,0.0209,-0.0058,-0.0209),"y"=c(-0.029,0.028,0.0250,-0.0028))

所以你必须计算多边形的中心:

  1. 获取对角线的等式
  2. 获得对角线的等式
  3. 获取线的交点(求解方程1 =方程2),这是形状的中心
  4. 计算中心与每侧的距离,并使用最小距离作为最小半径。
  5. 绘制前一个计算半径的圆圈。
  6. 应该很容易对这个特定的例子进行所有计算。

答案 1 :(得分:1)

我希望这会对你有所帮助。古德勒克

pack.circles <- function(config, size=c(100, 100), max.iter=1000, overlap=0) {
#
# Simple circle packing algorithm based on inverse size weighted repulsion
#
# config   - matrix with two cols: radius, N
# size     - width and height of bounding rectangle
# max.iter - maximum number of iterations to try
# overlap  - allowable overlap expressed as proportion of joint radii

# ============================================================================
#  Global constants
# ============================================================================
# round-off tolerance
TOL <- 0.0001

# convert overlap to proportion of radius
if (overlap < 0 | overlap >= 1) {
  stop("overlap should be in the range [0, 1)")
}
PRADIUS <- 1 - overlap

NCIRCLES <- sum(config[,2])

# ============================================================================
#  Helper function - Draw a circle
# ============================================================================
draw.circle <- function(x, y, r, col) { 
  lines( cos(seq(0, 2*pi, pi/180)) * r + x, sin(seq(0, 2*pi, pi/180)) * r + y , col=col )
}


# ============================================================================
#  Helper function - Move two circles apart. The proportion of the required
#  distance moved by each circle is proportional to the size of the other 
#  circle. For example, If a c1 with radius r1 overlaps c2 with radius r2,
#  and the movement distance required to separate them is ds, then c1 will
#  move ds * r2 / (r1 + r2) while c2 will move ds * r1 / (r1 + r2). Thus,
#  when a big circle overlaps a little one, the little one moves a lot while
#  the big one moves a little.
# ============================================================================
repel <- function(xyr, c0, c1) {
  dx <- xyr[c1, 1] - xyr[c0, 1]
  dy <- xyr[c1, 2] - xyr[c0, 2]
  d <- sqrt(dx*dx + dy*dy)
  r <- xyr[c1, 3] + xyr[c0, 3]
  w0 <- xyr[c1, 3] / r
  w1 <- xyr[c0, 3] / r

if (d < r - TOL) {
  p <- (r - d) / d
  xyr[c1, 1] <<- toroid(xyr[c1, 1] + p*dx*w1, 1)
  xyr[c1, 2] <<- toroid(xyr[c1, 2] + p*dy*w1, 2)
  xyr[c0, 1] <<- toroid(xyr[c0, 1] - p*dx*w0, 1)
  xyr[c0, 2] <<- toroid(xyr[c0, 2] - p*dy*w0, 2)

  return(TRUE)
}

  return(FALSE)
}


# ============================================================================
#  Helper function - Adjust a coordinate such that if it is distance d beyond
#  an edge (ie. outside the area) it is moved to be distance d inside the 
#  opposite edge. This has the effect of treating the area as a toroid.
# ============================================================================
toroid <- function(coord, axis) {
  tcoord <- coord

  if (coord < 0) {
    tcoord <- coord + size[axis]
  } else if (coord >= size[axis]) {
    tcoord <- coord - size[axis]
  }

  tcoord
}


# ============================================================================
#  Main program
# ============================================================================

# ------------------------------------------
# create a random initial layout
# ------------------------------------------
xyr <- matrix(0, NCIRCLES, 3)

pos0 <- 1
for (i in 1:nrow(config)) {
  pos1 <- pos0 + config[i,2] - 1
  xyr[pos0:pos1, 1] <- runif(config[i, 2], 0, size[1])
  xyr[pos0:pos1, 2] <- runif(config[i, 2], 0, size[2])
  xyr[pos0:pos1, 3] <- config[i, 1] * PRADIUS
  pos0 <- pos1 + 1
}

# ------------------------------------------
# iteratively adjust the layout
# ------------------------------------------
for (iter in 1:max.iter) {
  moved <- FALSE
  for (i in 1:(NCIRCLES-1)) {
    for (j in (i+1):NCIRCLES) {
      if (repel(xyr, i, j)) {
        moved <- TRUE
      }
    }
  }
  if (!moved) break
}

cat(paste(iter, "iterations\n"));

# ------------------------------------------
# draw the layout
# ------------------------------------------
plot(0, type="n", xlab="x", xlim=c(0,size[1]), ylab="y", ylim=c(0, size[2]))

xyr[, 3] <- xyr[, 3] / PRADIUS
for (i in 1:nrow(xyr)) {
  draw.circle(xyr[i, 1], xyr[i, 2], xyr[i, 3], "gray")
}

# ------------------------------------------
# return the layout
# ------------------------------------------
colnames(xyr) <- c("x", "y", "radius")
invisible(xyr) 
}

source