R中的凸包

机器算法验证 r
2022-03-23 08:38:31

我必须绘制一个多边形,它将连接R图中的四个顶点。为此,我需要
具有最小 Y 值的 X 的最小值。

X <- c(-62,  -40,   9,  13,  26,  27,  27)
Y <- c( 7, -14,  10,   9,  -8, -16,  12)
plot(x = X, y = Y)
abline(h = 0, v = 0, lty = 2.5, col = "green", lwd = 2)

在此处输入图像描述

我很难找到四个顶点

  • X 和 Y 的最小值(即 (-40, -14))
  • X 的最小值和 Y 的最大值(即 (-62, 7))
  • X 的最大值和 Y 的最小值(即 ( 27, -16))
  • X 和 Y 的最大值(即 ( 27, 12))

在 R。

2个回答

我认为您想要数据的凸包。尝试这个

library(grDevices) # load grDevices package
df <- data.frame(X = c(-62,  -40,   9,  13,  26,  27,  27),
                 Y = c( 7, -14,  10,   9,  -8, -16,  12)) # store X,Y together
con.hull.pos <- chull(df) # find positions of convex hull
con.hull <- rbind(df[con.hull.pos,],df[con.hull.pos[1],]) # get coordinates for convex hull
plot(Y ~ X, data = df) # plot data
lines(con.hull) # add lines for convex hull

编辑

如果您想从原点添加一条线到凸包的每一侧,使得每条线都垂直于凸包,请尝试以下操作:

getPerpPoints <- function(mat) {
  # mat: 2x2 matrix with first row corresponding to first point
  #      on the line and second row corresponding to second
  #      point on the line
  #
  # output: two points which define the line going from the side
  #         to the origin

  # store the inputs more conveniently
  x <- mat[,1]
  y <- mat[,2]

  # define a new matrix to hold the output
  out <- matrix(0, nrow = 2, ncol = 2)

  #  handle special case of vertical line
  if(diff(x) == 0) {
    xnew <- x[1]
  }
  else {
    # find point on original line
    xnew <- (diff(y) / diff(x)) * x[1] - y[1]
    xnew <- xnew / (diff(y) / diff(x) + diff(x) / diff(y))
  }
  ynew <- -(diff(x) / diff(y)) * xnew

  # put new point in second row of matrix
  out[2,] <- c(xnew, ynew)

  return(out = out)
}

绘制初始点以及数据的凸包后,运行上面的代码和以下代码:

for(i in 1:4) {
  lines(getPerpPoints(con.hull[i:(i+1),]))
}

请记住,从原点到每一侧的一些线不会在数据凸包的内部终止。这是我得到的输出:

在此处输入图像描述

我不是 100% 确定我正在关注你正在尝试做的事情abline,但也许这会让你朝着正确的方向前进。您可以使用该函数which.min()which.max()从向量中返回最小值或最大值。您可以将其与[运算符结合使用,以索引具有该条件的第二个向量。例如:

X[which.min(Y)]
X[which.max(Y)]

编辑以解决问题中的其他详细信息

您可以索引 Y 向量本身......以及 X 向量的 X 向量,而不是使用 Y 向量的最小/最大值来索引 X 向量:

c(X[which.min(X)], Y[which.min(Y)])
c(X[which.min(X)], Y[which.max(Y)])
c(X[which.max(X)], Y[which.min(Y)])
c(X[which.max(X)], Y[which.max(Y)])

编辑#2:

您想找到数据的凸包。这是你如何去做的:

#Make a data.frame out of your vectors
dat <- data.frame(X = X, Y = Y)
#Compute the convex hull. THis returns the index for the X and Y coordinates
c.hull <- chull(dat)
#You need five points to draw four line segments, so we add the fist set of points at the end
c.hull <- c(c.hull, c.hull[1])
#Here's how we get the points back
#Extract the points from the convex hull. Note we are using the row indices again.
dat[c.hull ,]
#Make a pretty plot
with(dat, plot(X,Y))
lines(dat[c.hull ,], col = "pink", lwd = 3)

###Note if you wanted the bounding box
library(spatstat)
box <- bounding.box.xy(dat)
plot(box, add = TRUE, lwd = 3)

#Retrieve bounding box points
with(box, expand.grid(xrange, yrange))

正如所承诺的,你的漂亮情节:

在此处输入图像描述