如何生成一个椭圆柱,用随机分布的点填充它,并测量R中这些点之间的重叠示例

nqwrtyyt  于 2023-01-22  发布在  其他
关注(0)|答案(2)|浏览(133)

我想确定一个随机分布的A类物体在椭圆柱体中占据或接触(重叠)同一空间的概率,然后我想多次循环这个模拟,以生成一个更可靠的概率值。
我可以使用形状包绘制椭圆柱:

library(shape)
emptyplot(c(-5, 5), c(-15, 15), main = "filled elliptic cylinder")
filledcylinder(rx = 9, ry = 5, len= 2, angle = 00, col = "white",  
               lcol = "black", lcolint = "grey")

我不知道如何将点(即对象A和B)添加到这个图形中。但是,我怀疑图形表达不是完成这个任务的方法(尽管我发现可视化很有帮助)。我怀疑一个更好的方法是创建一个函数来描述椭圆柱,类似于下面示例中的圆锥,并在没有图形输出的情况下运行模拟:

# Create a function to describe a cone
cone <- function(x, y){
  sqrt(x ^ 2 + y ^ 2)
}

# prepare variables.
x <- y <- seq(-1, 1, length = 30)
z <- outer(x, y, cone)

# plot as a 3D surface for visual reference (even though I actually want a volume)
persp(x, y, z,
      main="Perspective Plot of a Cone",
      zlab = "Height",
      theta = 30, phi = 15,
      col = "orange", shade = 0.4)

遗憾的是,我不知道如何对我的椭圆柱体进行描述。我知道下面来源中描述椭圆柱体的参数:
https://mathworld.wolfram.com/EllipticCylinder.html
可惜我不太懂,我希望我填好的圆柱体中给出的尺寸可以作为一个指南。最终尺寸值并不重要,重要的是可以输入值的代码结构。
至于对象:
假设有50个A型对象和50个B型对象,大小分别为x=0.4,y=0.4,z=0.4(与我的图形椭圆柱示例中的单位相同)。
所有物体应随机分布在椭圆柱体的体积内,但A类物体不能与另一A类物体重叠,B类物体不能与另一B类物体重叠。A类物体可与B类物体重叠。
我想输出给定体积中与任何B型物体重叠的A型物体的数量,这个数量是A型物体总数的百分比,以及每次运行模拟时所有物体总数的百分比。
我甚至不知道该怎么开始。
如果你能帮忙的话,恐怕统计学、几何学和非基本的R表达式需要像对一个(不是特别聪明的)孩子一样解释。
非常非常感谢您抽出时间!

k2fxgqgv

k2fxgqgv1#

一个带有大量注解代码的实现。它假设A型和B型对象必须完全位于椭圆柱体中。

library(data.table)

rObj <- function(rx, ry, h, n, dims, eps = 2) {
  # Function to create a random sample (by rejection) of non-overlapping
  # rectangular prism objects inside an elliptical cylinder whose ellipse is
  # centered at x = 0, y = 0 and whose height ranges from -dims[3]/2 to h -
  # dims[3]/2. The objects have dimensions (x, y, z) = dims, and all edges are
  # parallel or orthogonal to each of the x, y, or z axes.
  # INPUTS:
  #   rx:   length of the ellipse
  #   ry:   width of the ellipse
  #   h:    height of the elliptical cylinder
  #   n:    number of non-overlapping objects to return
  #   dims: dimensions of the rectangular prism objects (vector of length 3)
  #   eps:  oversampling factor
  # OUTPUT: a data.table with 3 columns and n rows. Each row gives the
  #         coordinates of the centroid of a sampled object
  dt <- data.table()
  while(nrow(dt) < n) {
    # increase oversampling if it is not the first pass
    if (nrow(dt)) eps <- eps*2
    rho <- sqrt(runif(eps*n))
    phi <- runif(eps*n, 0, 2*pi)
    dt <- data.table(
      # sample object centroids
      # see https://stackoverflow.com/questions/5529148/algorithm-calculate-pseudo-random-point-inside-an-ellipse
      # First, uniformly sample on an ellipse centered on x = 0, y = 0,
      # with xlength = rx - dims[1] and ylength = ry - dims[2]
      # (any object with a centroid outside of this ellipse will stick out of
      # the elliptical cylinder, although some with a centroid within the
      # smaller ellipse will still stick out of the elliptical cylinder).
      x = (rx - dims[1])/2*rho*cos(phi),
      y = (ry - dims[2])/2*rho*sin(phi),
      # uniformly sample centroid heights
      z = runif(eps*n, 0, h - dims[3])
    )[
      # remove objects that stick out of bounds
      # The ellipse satisfies (x/(rx/2))^2 + (y/(ry/2))^2 = 1, which is the
      # same as (x/rx)^2 + (y/ry)^2 = 0.25. Taking advantage of symmetry, add
      # half of the x and y dimensions of the objects to the absolute value of
      # x and y (the object corner furthest from the foci of the ellipse) and
      # check if the result satisfies the standard equation.
      ((abs(x) + dims[1]/2)/rx)^2 + ((abs(y) + dims[2]/2)/ry)^2 < 0.25
    ][
      # remove objects that overlap a previously placed object
      # Since each rectangular prism object is oriented with the x, y, z axes,
      # two objects overlap if they are closer than their lengths in each
      # dimension.
      tabulate(
        sequence((.N - 1L):1, 2:.N)[ # row numbers (always keep the first row)
          (dist(x) < dims[1]) & (dist(y) < dims[2]) & (dist(z) < dims[3])
        ],
        .N
      ) == 0L
    ]
  }
  dt[1:n] # keep the first n objects
}

# function to get pairwise distances between two vectors
dist2 <- function(x, y) abs(outer(x, y, "-"))

fsim <- function(rx, ry, h, nA, nB, dimA, dimB, nreps, eps = 2) {
  # function to simulate placement of A and B rectangular prism objects inside
  # an elliptical cylinder and count the number of A-type objects that
  # intersect at least one B-type object. All object edges are parallel or
  # orthogonal to each of the x, y, or z axes.
  
  # INPUTS:
  #   rx:     length of the ellipse
  #   ry:     width of the ellipses
  #   h:      height of the elliptical cylinder
  #   nA:     number of non-overlapping A-type objects to return
  #   nB:     number of non-overlapping B-type objects to return
  #   dimX:   dimensions of the rectangular prism objects (vector of length 3)
  #   nreps:  the number of replications to simulate
  #   eps:    oversampling factor when randomly sampling non-overlapping objects
  #           by rejection
  # OUTPUT: vector of length "nreps" giving the number of A-type objects that
  # intersect at least one B-type object for each replication
  dims <- rowMeans(cbind(dimA, dimB)) # average dimensions of the A and B objects
  out <- integer(nreps) # initialize the output vector
  # repeat the simulation "nreps" times
  for (i in 1:nreps) {
    # get the coordinates of the A- and B-type objects' centroids
    A <- rObj(rx, ry, h, nA, dimA, eps)
    B <- rObj(rx, ry, h, nB, dimB, eps)
    # count the number of A-type objects that intersect at least one B-type
    # object
    out[i] <- sum(rowSums((dist2(A$x, B$x) < dims[1])*(dist2(A$y, B$y) < dims[2])*(dist2(A$z, B$z) < dims[3])) != 0L)
  }
  
  out
}

时间10K模拟复制:

system.time(overlaps <- fsim(9, 5, 2, 50L, 50L, rep(0.4, 3), rep(0.4, 3), 1e4L))
#>    user  system elapsed 
#>   27.19    0.25   27.67
mean(overlaps)
#> [1] 18.7408
ktecyv1j

ktecyv1j2#

一种近似求解这个问题的方法是将物体离散化。将一个体积设置为一个三维的零数组,然后随机地一次生成一个形状的参数。
对于每个生成的形状,查找将位于该形状内部的数组的所有元素。如果任何位置将位于圆柱体外部或与同一类型的形状重叠,请重试。获得法律的形状后,标记这些数组条目(例如,类型A为1,类型B为2)。首先执行所有类型A,然后执行所有类型B,并记录形状B占用先前为形状A标记的空间的次数。

相关问题