在 rgl 中绘制带孔的多边形?

问题描述 投票:0回答:1

我有各种多边形,是用

terra
包创建的,我想使用
rgl
包来绘制它们。但它们有漏洞。我似乎无法理解如何使用
rgl
来做到这一点。在
triangulate()
函数的帮助文件示例中,它清楚地表明可以绘制带孔的多边形。我尝试将此示例改编为另一个示例,但失败了。这是我的代码:

library(rgl)
library(terra)

# dummy data
geom <- as.matrix(data.frame(
  "object" = 1,
  "part" = 1,
  "x" = c(1,2,6,7,1,3,3,5,3,5,6,6,5),
  "y" = c(1,5,5,3,1,3,4,4,3,3,4,3,3),
  "hole" = c(rep(0,5), rep(1,4), rep(2,4))))

# show in 2d plot
poly <- terra::vect(geom, "polygons")
terra::plot(poly, col = "forestgreen")

# prepare coordinates
x <- c(geom[geom[,5] == 0,3], NA, geom[geom[,5] == 1,3], NA, geom[geom[,5] == 2,3])
y <- c(geom[geom[,5] == 0,4], NA, geom[geom[,5] == 1,4], NA, geom[geom[,5] == 2,4])

# show in 2d plot
plot(x, y, type = "n")
polygon(x, y)

# try to triangulate
triangulate(x, y, plot = TRUE)

# show in 3d plot
open3d()
polygon3d(x, y, 0, col = "red")

我总是得到

Error in processOutside(i) : Cannot triangulate polygon
。根据我理解帮助文件中的示例,我的代码应该可以工作。我的理解是,我只需用
NA
将孔与主多边形分开。我是不是错过了什么?

r terra rgl
1个回答
0
投票

这是

rgl::triangulate()
函数中的错误或限制,对于两个 原因。

主要原因是三角测量是一个困难的数值问题:它需要找出哪些顶点三元组可以形成不与多边形区域之外的区域重叠的三角形。 当顶点对齐时,测试有时会由于舍入错误而产生不正确的结果。

因此,您可以做的一件事就是避免让顶点全部对齐。 例如,创建

x
y
向量后,您可以将它们替换为
jitter(x, factor = 0.01)
jitter(y, factor = 0.01)
,这会为每个值添加少量模糊并避免共线性问题。 这会稍微扭曲您的数据,但您可能不会在图中注意到它。 如果您确实需要,您可以使用抖动数据的三角剖分来定义真实数据的三角剖分。

另一个问题是确定孔是孔还是重叠多边形。 最好对顶点的排序保持一致,例如围绕要包含的区域顺时针旋转,围绕孔逆时针旋转。 (这可能是一个实际的要求,但我认为

triangulate()
会尝试修复问题,如果可以的话。)

因此,通过这两项更改,有时我可以让它发挥作用:

library(rgl)

set.seed(4)

# dummy data
geom <- as.matrix(data.frame(
  "object" = 1,
  "part" = 1,
  "x" = c(1,2,6,7,1,3,3,5,3,5,6,6,5),
  "y" = c(1,5,5,3,1,3,4,4,3,3,4,3,3),
  "hole" = c(rep(0,5), rep(1,4), rep(2,4))))

# prepare coordinates
x <- c(geom[geom[,5] == 0,3], NA, 
       rev(geom[geom[,5] == 1,3]), NA, 
       rev(geom[geom[,5] == 2,3]))
y <- c(geom[geom[,5] == 0,4], NA, 
       rev(geom[geom[,5] == 1,4]), NA, 
       rev(geom[geom[,5] == 2,4]))

x <- jitter(x, factor = 0.01)
y <- jitter(y, factor = 0.01)

# show in 2d plot
plot(x, y, type = "n")

# try to triangulate
triangulate(x, y, plot = TRUE)

#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
#> [1,]    5    5    4   12   12    4    3    8    2     2     3     1     5     5
#> [2,]   13    4   14    8    3    3    2    7    9     1    12     5    10     7
#> [3,]   12   13   13    5    8   14    8    5    8     9    14     9     9    10
#>      [,15]
#> [1,]    12
#> [2,]    15
#> [3,]    14
#> attr(,"nextvert")
#>  [1]  5  1  2  3  4 NA 10  7  8  9 NA 15 12 13 14

创建于 2024-09-25,使用 reprex v2.1.1

我说“有时”,因为使用一些

set.seed()
值它仍然会失败。

© www.soinside.com 2019 - 2024. All rights reserved.