根据宽度和高度将列表索引转换为 3D 位置

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

我正在用 Python 开发 CPU 体素光线追踪器。由于涉及大量昂贵的计算,一切都必须尽可能高效,尤其是在空间中存储和获取点数据。我首先将 2D 和 3D 数据存储在按字符串位置索引的字典中,例如:

data["4,16"] == "solid"
。由于将位置与字符串相互转换的成本很高,而字典比列表慢,因此我正在转向更有效的系统,将所有内容存储在有序数组中,并使用索引来确定条目引用的位置。我已经在 2D 中成功运行了:

# Returns x, y position from index i based on width
def index_vec2(i: int, width: int):
    return math.floor(i % width), math.floor(i / width)

假设您有一个 4x4 的正方形:如果数组包含 16 个条目,您很容易知道索引 3 代表位置

x == 3, y == 0
,然后索引 4 代表位置
x == 0, y == 1
。该函数只需要矩形宽度来推断这一点,高度不是必需的,因为不需要确保整个区域被填充或额外的条目不会溢出。

我正在尝试将相同的概念扩展到 3D:您将

i
索引传递给函数,在这种情况下,它需要知道宽度和高度才能计算深度。我有点挣扎,因为第三轴的数学更加复杂……如果我再花几个小时思考,我可能会弄清楚,但在这里为其他尝试的人提供答案似乎也是有益的同样的事情。

# Returns x, y, z position from index i based on width and height
def index_vec3(i: int, width: int, height: int):
    return math.floor(i % width), math.floor(i / width), math.floor(i / (width * height))

目前这似乎准确地报告了 X 和 Z,但我不知道如何处理 Y。最初它开始得很好,每超过宽度一次

i
就会增加一次。问题是,一旦我们进入下一个 Z 层,Y 不会返回到 0 并重新开始,它会一直攀升到 15。使用
for i in range(0, 64): index_vec3(i, 4, 4)
(模拟迭代 4x4x4 立方体)我得到以下结果:

0,0,0
1,0,0
2,0,0
3,0,0
0,1,0
1,1,0
2,1,0
3,1,0
0,2,0
1,2,0
2,2,0
3,2,0
0,3,0
1,3,0
2,3,0
3,3,0
0,4,1
1,4,1
2,4,1
3,4,1
0,5,1
1,5,1
2,5,1
3,5,1
0,6,1
1,6,1
2,6,1
3,6,1
0,7,1
1,7,1
2,7,1
3,7,1
0,8,2
1,8,2
2,8,2
3,8,2
0,9,2
1,9,2
2,9,2
3,9,2
0,10,2
1,10,2
2,10,2
3,10,2
0,11,2
1,11,2
2,11,2
3,11,2
0,12,3
1,12,3
2,12,3
3,12,3
0,13,3
1,13,3
2,13,3
3,13,3
0,14,3
1,14,3
2,14,3
3,14,3
0,15,3
1,15,3
2,15,3
3,15,3

如何提高我的数学能力以及实现第三轴的最简单形式是什么?唯一的规则是没有循环或增量,这会欺骗优化并抵消性能优势,每个轴必须通过基于宽度和高度的简单数学转换

i
来确定。希望它足够简单,可以保持一句台词,但这不是强制性的。

python python-3.x math vector 3d
1个回答
0
投票
def index_vec3(i,width,height):
  z,remainder=divmod(i,width*height)
  y,x=divmod(remainder, width)
  return (x,y,z)
© www.soinside.com 2019 - 2024. All rights reserved.