有没有人有一个聪明的主意,如何从图像中创建 n 个矩形图块,每个图块的大小都不同,并且没有重叠。下面给出的解决方案仅限于 n = 4。
randomTiles <- function(w, h, n){
if(sample(c(TRUE, FALSE), 1)){
tl <- c(0, sample(10:w-10, 1), 0, sample(round(h/10):h-round(h/10), 1))
bl <- c(0, sample(tl[2]:w-round(w/10), 1), tl[4], h)
tr <- c(tl[2], w, 0, tl[4])
br <- c(bl[2], w, tl[4], h)
}else{
tl <- c(0, sample(10:w-10, 1), 0, sample(round(h/10):h-round(h/10), 1))
tr <- c(tl[2], w, 0, sample(tl[4]:h-round(h/10), 1))
bl <- c(0, tl[2], tl[4], h)
br <- c(tl[2], w, tr[4], h)
}
tileFrame <- data.frame(xleft = c(tl[1], bl[1], tr[1], br[1]),
ybottom = c(tl[3], bl[3], tr[3], br[3]),
xright = c(tl[2], bl[2], tr[2], br[2]),
ytop = c(tl[4], bl[4], tr[4], br[4]),
col = rgb(runif(4), runif(4), runif(4)))
return(tileFrame)
}
h <- 100
w <- 120
n <- 4
op <- par(mfrow = c(2,2))
for(i in 1:4){
plot(h, xlim = c(0, w), ylim = c(h, 0), type = "n", xlab = "WIDTH", ylab = "HIGHT")
tiles <- randomTiles(w = w, h = h, n = n)
rect(tiles[,1], tiles[,2], tiles[,3], tiles[,4], col = tiles[,5])
}
par(op)
感谢您的提示...
答案 0 :(得分:1)
我有点无聊,所以我试了一下。效果很好,但我不是随机生成器专家,所以很有可能在此代码生成的矩形位置中存在一些隐藏的偏差。
更新:这确实引起了我的注意。我认为第一个版本实际上偏向于制作越来越小的矩形。我认为我已经更新了代码,以至于不再发生这种情况。
library(data.tree)
library(tidyverse)
random_rects <- function (x, y, n) {
rand_leaf <- function (nd) {
while (data.tree::isNotLeaf(nd)) {
nd <- if (runif(1) > .5) nd$r else nd$l
}
nd
}
split_node <- function (nd) {
nd$div <- runif(1)
nd$dir <- ifelse(runif(1) > .5, "h", "v")
nd$AddChild("l")
nd$AddChild("r")
}
set_dims <- function (nd) {
p <- nd$parent
nd$x0 = p$x0
nd$x1 = p$x1
nd$y0 = p$y0
nd$y1 = p$y1
if (p$dir == "h") {
new_x <- p$x0 + (p$x1 - p$x0)*p$div
if (nd$name == "l") {
nd$x1 <- new_x
} else {
nd$x0 <- new_x
}
} else {
new_y <- p$y0 + (p$y1 - p$y0)*p$div
if (nd$name == "l") {
nd$y1 <- new_y
} else {
nd$y0 <- new_y
}
}
}
get_dims <- function (nd) {
tibble::tibble(x0 = nd$x0, x1 = nd$x1, y0 = nd$y0, y1 = nd$y1)
}
root <- data.tree::Node$new("home")
for (i in seq_len(n - 1)) {
nd <- rand_leaf(root)
split_node(nd)
}
root$x0 <- 0
root$x1 <- x
root$y0 <- 0
root$y1 <- y
root$Do(set_dims, traversal = "pre-order", filterFun = data.tree::isNotRoot)
dfs <- purrr::map(data.tree::Traverse(root, filterFun = data.tree::isLeaf), get_dims)
list(tree = root, df = dplyr::bind_rows(dfs))
}
set.seed(1)
rect_list <- purrr::rerun(10, random_rects(40, 100, 20))
df <- dplyr::bind_rows(purrr::map(rect_list, ~ dplyr::mutate(.x$df, pos = factor(1:n()))), .id = "rep")
ggplot(df, aes(xmin = x0, xmax = x1, ymin = y0, ymax = y1, fill = pos)) +
geom_rect(alpha = .7) +
facet_wrap(~rep)
head(df)
#> # A tibble: 6 x 6
#> rep x0 x1 y0 y1 pos
#> <chr> <dbl> <dbl> <dbl> <dbl> <fct>
#> 1 1 0 15.3 0 3.56 1
#> 2 1 0 15.3 3.56 5.21 2
#> 3 1 0 15.3 5.21 5.47 3
#> 4 1 15.3 40 0 2.70 4
#> 5 1 15.3 25.3 2.70 5.47 5
#> 6 1 25.3 40 2.70 5.47 6
由reprex package(v0.2.1)于2018-11-11创建