gpt4 book ai didi

r - 用系统点栅格填充 3D 体

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:41:48 31 4
gpt4 key购买 nike

我有一组 3D 体。每个 Body 由 8 个点定义,每个点具有三个坐标。所有的物体都是立方体的或近似立方体的。我想用系统的点栅格“填充”立方体。坐标存储在简单的 data.frames 中。

我开发了以下代码来完成我想要的立方体:

# libraries
library(rgl)

# define example cube with 8 points
excube <- data.frame(
x = c(1,1,1,1,5,5,5,5),
y = c(1,1,4,4,1,1,4,4),
z = c(4,8,4,8,4,8,4,8)
)

# cubeconst: fill cube (defined by 8 corner points) with a 3D-point-raster
cubeconst <- function(x, y, z, res) {
cube <- data.frame()
xvec = seq(min(x), max(x), res)
yvec = seq(min(y), max(y), res)
zvec = seq(min(z), max(z), res)
for (xpoint in 1:length(xvec)) {
for (ypoint in 1:length(yvec)) {
for (zpoint in 1:length(zvec)) {
cube <- rbind(cube, c(xvec[xpoint], yvec[ypoint], zvec[zpoint]))
}
}
}
colnames(cube) <- c("x", "y", "z")
return(cube)
}

# apply cubeconst to excube
fcube <- cubeconst(x = excube$x, y = excube$y, z = excube$z, res = 0.5)

# plot result
plot3d(
fcube$x,
fcube$y,
fcube$z,
type = "p",
xlab = "x",
ylab = "y",
zlab = "z"
)

现在我正在寻找一种解决方案来“填充”近似于立方体的物体,例如以下物体:

# badcube
badcube <- data.frame(
x = c(1,1,1,1,5,5,5,5),
y = c(1,1,4,4,1,1,4,4),
z = c(4,10,4,12,4,8,4,8)
)

# plot badcube
plot3d(
badcube$x,
badcube$y,
badcube$z,
col = "red",
size = 10,
type = "p",
xlab = "x",
ylab = "y",
zlab = "z"
)

也许你能给我指出正确的方向。

最佳答案

您需要将六面体(奇怪的立方体)转换为单位立方体。下图显示了我的意思,并为我们提供了六边形顶点的编号方案。顶点 2 隐藏在立方体后面。

enter image description here

转换是从真实空间 x,y,z 到新坐标系 u,v,w,其中六边形是单位立方体。用于 hexa 的典型函数如下所示。

x = A + B*u + C*v + D*w + E*u*v + F*u*w + G*v*w + H*u*v*w

y 和 z 坐标的变换形式相同。您的立方体有 8 个角,因此您可以将它们代入以求解系数 A,B,...。单位坐标 u,v,w 在每个顶点都是 01,因此这大大简化了事情。

x0 = A                             // everything = zero
x1 = A + B // u = 1, others = zero
x2 = A + C // v = 1, ...
x4 = A + D // w = 1
x3 = A + B + C + E // u = v = 1
x5 = A + B + D + F // u = w = 1
x6 = A + C + D + G // v = w = 1
x7 = A + B + C + D + E + F + G + H // everything = 1

然后您必须求解 A,B,...。这很容易,因为您只需向前替换。 A 等于 x0B 等于 x1 - A,等等...您还必须为 yz 执行此操作,但是如果您的语言支持矢量运算,这可能可以在与 x 相同的步骤中完成。

获得系数后,您可以将点 u,v,w 转换为 x,y,z。现在,如果你有一个适用于 1x1x1 立方体的点生成方案,你可以将结果转换为原始的十六进制。您可以在发布的代码中保留相同的三重循环结构,并在 01 之间改变 u,v,w 以创建网格十六进制内的点数。

恐怕我不知道 r,所以我无法为您提供该语言的任何示例代码。不过,这里有一个快速的 python3 示例,只是为了证明它有效。

import matplotlib.pyplot as pp
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

np.random.seed(0)

cube = np.array([
[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0],
[0.0, 0.0, 1.0], [1.0, 0.0, 1.0], [0.0, 1.0, 1.0], [1.0, 1.0, 1.0]])

hexa = cube + 0.5*np.random.random(cube.shape)

edges = np.array([
[0, 1], [0, 2], [1, 3], [2, 3],
[0, 4], [1, 5], [2, 6], [3, 7],
[4, 5], [4, 6], [5, 7], [6, 7]])

def cubeToHexa(hexa, u, v, w):
A = hexa[0]
B = hexa[1] - A
C = hexa[2] - A
D = hexa[4] - A
E = hexa[3] - A - B - C
F = hexa[5] - A - B - D
G = hexa[6] - A - C - D
H = hexa[7] - A - B - C - D - E - F - G
xyz = (
A +
B*u[...,np.newaxis] +
C*v[...,np.newaxis] +
D*w[...,np.newaxis] +
E*u[...,np.newaxis]*v[...,np.newaxis] +
F*u[...,np.newaxis]*w[...,np.newaxis] +
G*v[...,np.newaxis]*w[...,np.newaxis] +
H*u[...,np.newaxis]*v[...,np.newaxis]*w[...,np.newaxis])
return xyz[...,0], xyz[...,1], xyz[...,2]

fg = pp.figure()
ax = fg.add_subplot(111, projection='3d')

temp = np.reshape(np.append(hexa[edges], np.nan*np.ones((12,1,3)), axis=1), (36,3))
ax.plot(temp[:,0], temp[:,1], temp[:,2], 'o-')

u, v, w = np.meshgrid(*[np.linspace(0, 1, 6)]*3)
x, y, z = cubeToHexa(hexa, u, v, w)
ax.plot(x.flatten(), y.flatten(), z.flatten(), 'o')

pp.show()

我不记得这种形式的转换的确切理由。这当然很容易解决,而且它没有平方项,所以 u,v,w 轴方向上的线映射到 x,y,z 中的直线.这意味着您的立方体边缘和面以及角都保证符合要求。不过,我缺乏数学来证明这一点,而且我也找不到任何可通过谷歌搜索的信息。我的知识来自对有限元方法教科书的遥远内存,这些转换在其中很常见。如果您需要更多信息,我建议您开始查看。

关于r - 用系统点栅格填充 3D 体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36115215/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com