在给定任意维度/位置的二进制数组/数字中选择 3 维点

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

我正在尝试使用二进制抽象 3D 点系统来加快速度。

假设我有一个任意的 3D“体积”,例如 8x8x8 单位。该体积由 512 位二进制数(本质上是一维线)定义。

如何在给定 3D 位置的数字中选择 0 或 1?我想知道是否有一组简单的二进制操作可以执行类似的操作,因为我见过类似的实现,但没有描述它们实际如何工作。

比如说,这个体积是从左到右定义的(x 轴上的 0-7),然后从前到后(y 轴上的 0-7),然后从下到上(z 轴上的 0-7),组成一个 8x8 的立方体。

基本上按照这些说明,

1, 1, 1
框中的
4x4x4
处的点在数组中将如下所示:

                          V - point 1,1,1
0000 0000 0000 0000 0000 0100 0000 0000 ...

二进制/按位数学中是否有某种方法可以沿 x > y > z 轴进行计数,并从给定 3D 点的数组中分离出二进制值?

本质上,我需要既能够读取该二进制值,又能够写入它......我认为有一种方法可以做到这一点

实际上,我可以将此二进制数转换为一维数组,并使用基本模数来选择正确的位置,但如果我可以用二进制加快速度,从长远来看,这确实会帮助我。

math binary mathematical-optimization
1个回答
0
投票

只需打包并重塑即可:

from typing import Any

import numpy as np

type ByteArray = np.ndarray[Any, np.dtype[np.uint8]]


def codes_to_cube(
    codes: np.ndarray,
) -> ByteArray:
    bits = np.unpackbits(codes)
    n = int(round(bits.size**(1/3)))
    return bits.reshape((n, n, n))


def cube_to_codes(
    cube: ByteArray,
) -> ByteArray:
    return np.packbits(cube.ravel())


def demo() -> None:
    rand = np.random.default_rng(seed=0)

    print('Encoding random bytes:')
    codes = rand.integers(
        size=512//8, low=0, high=256, dtype=np.uint8,
    )
    cube = codes_to_cube(codes)
    print(cube)
    print()

    decoded = cube_to_codes(cube)
    assert np.array_equal(decoded, codes)

    print('Decoding cube with selected non-zeros:')
    cube = np.zeros(shape=(8, 8, 8), dtype=np.uint8)
    cube[0, 0, 5] = 1
    cube[4, 1, 6] = 1
    cube[2, 7, 1] = 1
    codes = cube_to_codes(cube)
    print(codes)
    encoded = codes_to_cube(codes)
    assert np.array_equal(encoded, cube)


if __name__ == '__main__':
    demo()
Encoding random bytes:
[[[0 1 0 1 1 1 1 1]
  [1 0 0 0 0 0 1 0]
  [1 1 0 0 0 0 1 0]
  [1 1 0 1 1 0 0 1]
  [1 1 0 0 1 1 1 1]
  [1 1 1 0 1 0 1 1]
  [0 0 0 0 1 1 1 1]
  [1 0 1 0 0 0 1 1]]

 [[0 0 1 0 0 0 0 1]
  [1 1 0 1 0 1 1 1]
  [1 1 0 1 1 0 0 1]
  [1 0 0 0 0 0 1 0]
  [1 1 1 1 1 0 0 0]
  [1 0 1 1 1 1 0 1]
  [0 0 0 1 0 0 0 0]
  [0 1 0 0 0 1 0 1]]

 [[1 0 1 1 1 0 0 0]
  [1 1 1 0 1 0 0 0]
  [1 1 0 0 1 1 0 1]
  [0 1 0 0 1 1 1 0]
  [1 0 1 0 1 0 0 1]
  [0 0 1 1 1 1 0 1]
  [0 1 1 1 1 1 0 1]
  [0 0 0 0 1 0 1 0]]

 [[0 0 0 1 1 1 0 1]
  [1 1 1 1 0 0 0 0]
  [0 1 0 0 0 0 1 0]
  [0 0 0 1 0 0 1 1]
  [1 0 1 1 0 1 1 0]
  [0 0 1 0 0 1 1 1]
  [0 0 1 1 1 0 1 1]
  [0 0 0 0 0 1 0 0]]

 [[0 0 1 1 1 0 1 1]
  [0 1 0 1 0 0 0 1]
  [1 1 0 1 1 1 1 0]
  [0 0 1 0 1 1 0 0]
  [0 1 1 1 1 0 0 0]
  [0 1 1 1 1 0 1 0]
  [0 0 1 1 0 0 1 0]
  [1 1 0 1 0 0 0 0]]

 [[0 1 0 0 1 1 1 0]
  [0 0 0 1 1 1 0 0]
  [0 1 0 0 0 0 0 0]
  [1 0 1 0 0 1 1 0]
  [0 1 1 1 1 0 0 1]
  [0 1 0 1 1 0 0 1]
  [1 0 1 0 1 0 1 0]
  [1 1 1 0 1 0 0 1]]

 [[0 1 1 1 1 1 1 1]
  [1 0 1 1 0 0 1 0]
  [1 1 1 0 1 1 0 1]
  [1 0 0 0 0 0 0 0]
  [0 1 1 1 0 0 0 1]
  [0 1 1 1 1 0 1 1]
  [0 1 0 0 1 1 0 0]
  [1 0 0 1 1 0 1 1]]

 [[0 1 0 0 0 1 0 1]
  [1 0 0 1 1 0 1 0]
  [1 0 0 0 0 0 1 0]
  [1 1 1 1 1 0 0 0]
  [0 1 0 1 1 1 1 1]
  [0 1 0 0 1 0 0 1]
  [1 1 0 0 0 0 0 0]
  [1 0 1 1 1 0 1 0]]]

Decoding cube with selected non-zeros:
[ 4  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 64
  0  0  0  0  0  0  0  0  0  2  0  0  0  0  0  0  0  0  0  0  0  0  0  0
  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0]
© www.soinside.com 2019 - 2024. All rights reserved.