在考虑网格相对位置的情况下,通过与另一个网格的逐点距离为网格着色

时间:2020-06-17 03:30:45

标签: r colors 3d heatmap rgl

我有一个较早的post,询问如何创建热图来演示两个网格之间的差异。那篇文章是关于如何选择色标的。为了分配颜色,必须首先计算要比较的两个网格之间的顶点方向距离。在那篇文章中,这是通过R的Morpho包中的meshDist函数完成的。

让我感到困惑的是,我并不特别了解meshDist是如何在引擎盖下计算顶点方向距离的。我想要的是两个网格(例如,mesh1上的(x1,y1,z1)与mesh2上的(x2,y2,z2)同源)之间的顶点之间的欧几里得距离,估计为sqrt(sum((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2))。但是,这给出的值与meshDist返回的值有些不同。当然,我可以直接使用自己计算出的欧几里得距离来绘制网格的热图。但是欧几里德距离不能反映两个网格的相对位置。

当重叠两个网格时,我希望用与表示网格2更加突出的部分所用的颜色不同的颜色来着色网格1更加突出的部分。 meshDist(对我而言)神奇地考虑了相对网格位置。返回的正值表示mesh1相对突出,而负值表示mesh2更加突出。相反,我计算的欧几里得距离忽略了此类信息。我想问一下是否有可能像meshDist那样获得正负的Eulcidean距离,这样生成的热图不仅可以说明差异的大小,还可以说明两个网格的相对位置?

完整代码,包括在其上绘制网格和叠加颜色,如下所示:

library(Morpho)
library(xlsx)
library(rgl)
library(RColorBrewer)
library(tidyverse)


mshape1 <- read.xlsx("...\\vb1.xlsx", sheetIndex = 1, header = F)
mshape2 <- read.xlsx("...\\vb2.xlsx", sheetIndex = 1, header = F)

it <- read.xlsx("...\\it.xlsx", sheetIndex = 1, header = F)

# Preparation for use in tmesh3d
vb_mat_mshape1 <- t(mshape1)
vb_mat_mshape1 <- rbind(vb_mat_mshape1, 1)
rownames(vb_mat_mshape1) <- c("xpts", "ypts", "zpts", "")

vb_mat_mshape2 <- t(mshape2)
vb_mat_mshape2 <- rbind(vb_mat_mshape2, 1)
rownames(vb_mat_mshape2) <- c("xpts", "ypts", "zpts", "")

it_mat <- t(as.matrix(it))
rownames(it_mat) <- NULL

vertices1 <- c(vb_mat_mshape1)
vertices2 <- c(vb_mat_mshape2)

indices <- c(it_mat)

mesh1 <- tmesh3d(vertices = vertices1, indices = indices, homogeneous = TRUE, 
               material = NULL, normals = NULL, texcoords = NULL)
mesh2 <- tmesh3d(vertices = vertices2, indices = indices, homogeneous = TRUE, 
               material = NULL, normals = NULL, texcoords = NULL)

mesh1smooth <- addNormals(mesh1)
mesh2smooth <- addNormals(mesh2)

# Calculate mesh distance using meshDist function in Morpho package
mD <- meshDist(mesh1smooth, mesh2smooth)
pd <- mD$dists

######################## Assign color to vertext groups ######################## 
nlevel <- 99
# Method suggested by user2554330 [here][1]
limit <- max(abs(pd))
breaks <- -limit + (0:nlevel)*2*limit/nlevel

pd_cut <- cut(pd, breaks = breaks, include.lowest = TRUE)

col <- hcl.colors(nlevel, "RdBu")
col <- rev(col)

dat_col <- data.frame(pd = pd, pd_cut = pd_cut, group = as.numeric(pd_cut))
dat_col <- dat_col %>% 
           mutate(col = col[dat_col$group])

open3d()
shade3d(mesh1smooth, col=dat_col$col, specular = "#202020", polygon_offset = 1)

另一个问题是,尽管我可以使用上面的shape3d函数来生成热图,但默认情况下该函数不会创建颜色图例。虽然有一些用于创建热图的函数,允许我通过向函数提交顶点距离来获得看起来不错的颜色图例,但我不能保证这些函数像我所做的那样精确地创建颜色(这是user2554330建议的方法)。我该如何为我的网格热图准确地创建一个顶点颜色图例,使其具有几种中间颜色(包括中心颜色,即上面代码中的第50个col)与它们对应的顶点距离值(pd_cut)相匹配?

谢谢您的帮助。

0 个答案:

没有答案