[英]Can we identify the "black" faces of a plotted rgl mesh?
我有这个 rgl 网格:
该网格来自等值面。 原始等值面没有宽度,而此网格的宽度很小。
我有 function f
定义等值面f=0
,所以我可以计算每个顶点的梯度:
library(numDeriv)
normals <- apply(mesh$vb[-4L, ], 2L, function(v) {
grad(f, v)
})
但是如果我使用这些法线,我会得到一个黑色的“边”,因为正如我所说的那样有一个宽度,所以实际上橙色“边”和黑色“边”都是同一边:
理论上,如果我反转顶点v
法线使得f(v) < 0
,那会很好,但由于不精确,如果我这样做的话会有几个黑脸:
ff <- apply(mesh$vb[-4L, ], 2L, f)
normals[, ff < 0] <- -normals[, ff < 0]
mesh$normals <- normals
所以我想知道:有没有办法识别用黑色绘制的面孔? 这样我就可以反转这些面孔的法线。
法线附加到网格中的顶点,并且记录在it
三角形或四边形或ib
定义相邻的顶点。 所以你可以寻找一个顶点,它的法线与相邻的顶点非常不同(大致相反)。
这是一个例子。 在 R 中,网格显示与在 WebGL 中不同,因为 WebGL 代码忽略了法线的方向。 我已将 R 显示替换为下面的 output,但对您的原始问题更简单的解决方案可能只是使用 WebGL 显示而不是 R 显示。
set.seed(1234)
library(rgl)
# Set up a smooth mesh
mesh <- icosahedron3d(col="red") |> subdivision3d(2) |> addNormals()
str(mesh)
#> List of 4
#> $ material:List of 1
#> ..$ color: chr "red"
#> $ it : num [1:3, 1:320] 1 43 44 13 45 43 14 44 45 44 ...
#> $ vb : num [1:4, 1:162] -1.42e-14 1.01e+03 1.63e+03 2.32e+03 -1.42e-14 ...
#> $ normals : num [1:4, 1:162] 1.30e-16 5.26e-01 8.51e-01 1.00 -4.47e-18 ...
#> - attr(*, "class")= chr "mesh3d"
# Randomly choose two vertices, and flip their normals:
i <- sample(seq_len(ncol(mesh$vb)), 2)
mesh$normals[1:3, i] <- -mesh$normals[1:3, i]
# Show it, but note that rglwidget uses different shading rules, so the
# dark spots won't show up:
open3d()
#> glX
#> 1
shade3d(mesh)
# List all adjacent vertex numbers in a vector
adjacent <- as.numeric(rbind(mesh$it, mesh$it[1, ], NA))
# Extract the normals in Euclidean coordinates
normals <- asEuclidean2(mesh$normals)
# Compute the difference between adjacent normals
normaldiff <- (normals[, adjacent[-1]]
- normals[, adjacent[-length(adjacent)]])^2 |>
colSums() |>
sqrt()
# Select the big ones that are not NA
bad <- !is.na(normaldiff) & normaldiff > 1
# Which vertices show up a lot?
table(adjacent[c(bad, FALSE)])
#>
#> 23 24 28 78 79 80 83 86 94 95 98 100 102 104
#> 1 1 6 1 1 6 1 1 1 1 1 1 1 1
# Which vertices were originally chosen?
i
#> [1] 28 80
创建于 2023-06-03,使用reprex v2.0.2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.