如何在不对正方形进行硬编码的情况下在三角形的每一侧制作正方形?

How to make squares on each side of the triangle without hard-coding the squares?

我有一个包含 4 个点的 data.frame,当使用 geom_path:

连接时会创建一个三角形
library(ggplot2)

triangle = data.frame(x = c(0, 0.5, 1, 0),
                      y = c(0, 0.5, 0, 0))

ggplot(triangle, aes(x, y)) +
        geom_path()

现在,我想创建一个新的 data.frame(基于 triangle),它有 4 个点(例如 xminxmaxymin, ymax) 从三角形的边创建正方形(因此,这个 data.frame 将有 3 行(每个正方形)和 4 列(每个点)。

这是一个例子:

是否可以在不对正方形的边进行硬编码的情况下做到这一点?

由于正方形会成一定角度,您可能需要根据顶点的 x、y co-ordinates 来输出。这只需要一点触发。以下函数采用表示闭合三角形的 x、y 点的向量和 returns 每边正方形顶点的数据框:

make_squares <- function(x, y) {
  
  x1    <- x[-4]
  x2    <- x[-1]
  xdiff <- (x2 - x1)
    
  y1    <- y[-4]
  y2    <- y[-1]
  ydiff <- (y2 - y1)
  
  lengths <- sqrt(xdiff^2 + ydiff^2)
  angles  <- atan2(ydiff, xdiff)
  
  x3 <- x2 - sin(angles) * lengths
  x4 <- x1 - sin(angles) * lengths
  
  y3 <- y2 + cos(angles) * lengths
  y4 <- y1 + cos(angles) * lengths
  
  
  df <- data.frame(x = round(c(x1, x2, x3, x4, x1), 3),
                   y = round(c(y1, y2, y3, y4, y1), 3),
                   square = rep(1:3, 5))
  `row.names<-`(df[order(df$square),], NULL)
}

输出如下所示:

make_squares(triangle$x, triangle$y)
#>       x    y square
#> 1   0.0  0.0      1
#> 2   0.5  0.5      1
#> 3   0.0  1.0      1
#> 4  -0.5  0.5      1
#> 5   0.0  0.0      1
#> 6   0.5  0.5      2
#> 7   1.0  0.0      2
#> 8   1.5  0.5      2
#> 9   1.0  1.0      2
#> 10  0.5  0.5      2
#> 11  1.0  0.0      3
#> 12  0.0  0.0      3
#> 13  0.0 -1.0      3
#> 14  1.0 -1.0      3
#> 15  1.0  0.0      3

你可以像这样在你的情节中使用它:

ggplot(triangle, aes(x, y)) + 
  geom_path() +
  geom_polygon(data = make_squares(triangle$x, triangle$y),
               aes(group = square), fill = "green4", color = "black") +
  coord_equal()