Compare commits
6 commits
Author | SHA1 | Date | |
---|---|---|---|
69d875a5c8 | |||
0cd5270419 | |||
c56e93a617 | |||
ec8ba98b56 | |||
5a9224bdae | |||
800e7f306d |
4 changed files with 185 additions and 2 deletions
|
@ -7,10 +7,10 @@ With this module, you can store data in files easyly.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from warnings import deprecated
|
from deprecated import deprecated
|
||||||
|
|
||||||
|
|
||||||
@deprecated("This function is not safe to use!!!")
|
@deprecated(reason="This function is not safe to use!!!")
|
||||||
class DictFile:
|
class DictFile:
|
||||||
"""
|
"""
|
||||||
This class is not safe to use!
|
This class is not safe to use!
|
||||||
|
|
93
infinite_matrix.py
Normal file
93
infinite_matrix.py
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
from scipy.sparse import csc_array, csr_array
|
||||||
|
|
||||||
|
|
||||||
|
# --- How it works: (3D Matrix)---
|
||||||
|
# Matrices can only expand in all positive directions.
|
||||||
|
# That means, the zero point of the matrix stays at the same position while the matrix expands,
|
||||||
|
# but the opposite corner (where no xyz direction is zero) moves away from the zero point while it expands.
|
||||||
|
# If you draw a line through the zero point of the matrix and the opposite completely positive corner,
|
||||||
|
# you get the direction in that the matrix will expand. (this direction will change if you change the aspect ratio of -
|
||||||
|
# the matrix)
|
||||||
|
# But we need a matrix that can expand in the negative directions too.
|
||||||
|
# To create such a matrix, we use another matrix that we flip completely and put behind the zero point of a first -
|
||||||
|
# matrix, on the same expanding direction of the first matrix.
|
||||||
|
# Because the second matrix is flipped, our expanding direction can now go in the opposite direction,
|
||||||
|
# but because you cant create another cube from two cubes, we don't have a complete matrix.
|
||||||
|
# So we add six more matrices to make our infinite matrix expandable in the yz, x, y, xz, xy, z directions.
|
||||||
|
|
||||||
|
|
||||||
|
class Infinite3DMatrixCSC:
|
||||||
|
def __init__(self, size: tuple=(32, 32, 32), size_negative: tuple=(32, 32, 32)):
|
||||||
|
self.size = size
|
||||||
|
self.size_negative = size_negative
|
||||||
|
self.chunk_size = (
|
||||||
|
(size[0] + size_negative[0]) / 2,
|
||||||
|
(size[1] + size_negative[1]) / 2,
|
||||||
|
(size[2] + size_negative[2]) / 2
|
||||||
|
) # get average
|
||||||
|
|
||||||
|
px = size[0]
|
||||||
|
py = size[1]
|
||||||
|
pz = size[2]
|
||||||
|
nx = size_negative[0]
|
||||||
|
ny = size_negative[1]
|
||||||
|
nz = size_negative[2]
|
||||||
|
|
||||||
|
# if (
|
||||||
|
# not float(self.size[0]).is_integer() and
|
||||||
|
# not float(self.chunk_size[1]).is_integer() and
|
||||||
|
# not float(self.chunk_size[2]).is_integer()
|
||||||
|
# ): # if the size is possible
|
||||||
|
# raise ValueError("Cant calculate equal chunk size.")
|
||||||
|
|
||||||
|
self.xyz_matrix = csc_array(size) # create the 8 matrices
|
||||||
|
self.negative_matrix = csc_array(size_negative)
|
||||||
|
self.yz_matrix = csc_array((nx, py, pz))
|
||||||
|
self.x_matrix = csc_array((px, ny, nz))
|
||||||
|
self.y_matrix = csc_array((nx, py, nz))
|
||||||
|
self.xz_matrix = csc_array((px, ny, pz))
|
||||||
|
self.xy_matrix = csc_array((px, py, nz))
|
||||||
|
self.z_matrix = csc_array((nx, ny, pz)) # Nix, Nie, Pizza!
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
self.get_item(item)
|
||||||
|
|
||||||
|
def resize_matrices(self):
|
||||||
|
px = self.size[0]
|
||||||
|
py = self.size[1]
|
||||||
|
pz = self.size[2]
|
||||||
|
nx = self.size_negative[0]
|
||||||
|
ny = self.size_negative[1]
|
||||||
|
nz = self.size_negative[2]
|
||||||
|
|
||||||
|
self.xyz_matrix.resize(self.size)
|
||||||
|
|
||||||
|
|
||||||
|
def resize(self, new_size: tuple, new_size_negative: tuple):
|
||||||
|
if not new_size is None:
|
||||||
|
self.size = new_size
|
||||||
|
|
||||||
|
if not new_size_negative is None:
|
||||||
|
self.size_negative = new_size_negative
|
||||||
|
|
||||||
|
def expand(self, add_positive: tuple, add_negative: tuple):
|
||||||
|
if not add_positive is None:
|
||||||
|
self.size = coord_add(self.size, add_positive)
|
||||||
|
|
||||||
|
if not add_negative is None:
|
||||||
|
self.size_negative = coord_add(self.size_negative, add_negative)
|
||||||
|
|
||||||
|
def get_item(self, position: tuple):
|
||||||
|
x, y = position
|
||||||
|
|
||||||
|
|
||||||
|
def coord_add(coord1: tuple, coord2: tuple):
|
||||||
|
return coord1[0] + coord2[0], coord1[1] + coord2[1], coord1[2] + coord2[2]
|
||||||
|
|
||||||
|
def coord_sub(coord1: tuple, coord2: tuple):
|
||||||
|
return coord1[0] - coord2[0], coord1[1] - coord2[1], coord1[2] - coord2[2]
|
||||||
|
|
||||||
|
|
||||||
|
Infinite3DMatrixCSC((5, 5))
|
89
math/spvo.py
Normal file
89
math/spvo.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
"""
|
||||||
|
SPVO = Sparse Voxel Octree
|
||||||
|
|
||||||
|
A Sparse Voxel Octree is a way of storing multidimensional data. (In this case it is 3D Data.)
|
||||||
|
It works similarly to a Sparse Voxel Matrix, but it is a bit compressed.
|
||||||
|
In a Sparse Voxel Octree, you have a root-node. The root node gets split up into 8 child nodes,
|
||||||
|
which can be all split up into 8 more child nodes which can be split up too and so on.
|
||||||
|
Thanks to this "compression", there are no zero values on places where there is just air unlike as in a normal matrix.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class Node:
|
||||||
|
def __init__(self, data=None):
|
||||||
|
self.children = [None] * 8
|
||||||
|
self.leaf = True
|
||||||
|
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
|
||||||
|
class SparseVoxelOctree:
|
||||||
|
def __init__(self):
|
||||||
|
self.root_node = Node()
|
||||||
|
self.origin = (0, 0, 0)
|
||||||
|
|
||||||
|
def _get_child_index(self, x, y, z, size):
|
||||||
|
"""
|
||||||
|
Get the index of a child.
|
||||||
|
Index: The position of the node in the node parent's children list.
|
||||||
|
"""
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
|
||||||
|
if x >= size // 2: # x pos
|
||||||
|
# there are only 2 possible x coordinate values in a 2x2 cube, so we use the 1st bit in index for x
|
||||||
|
# xyz: the coordinates of the parent node
|
||||||
|
index |= 1 # set 1st bit to 1
|
||||||
|
x -= size // 2 # get parent x
|
||||||
|
|
||||||
|
# and the same for y and z
|
||||||
|
|
||||||
|
if y >= size // 2: # y pos
|
||||||
|
index |= 2
|
||||||
|
y -= size // 2
|
||||||
|
|
||||||
|
if z >= size // 2: # z pos
|
||||||
|
index |= 4
|
||||||
|
z -= size // 2
|
||||||
|
|
||||||
|
return index, x, y, z
|
||||||
|
|
||||||
|
def _extend_tree(self, x, y, z):
|
||||||
|
new_root = Node()
|
||||||
|
new_root.leaf = False
|
||||||
|
|
||||||
|
index, nx, ny, nz = self._get_child_index(x, y, z, 2)
|
||||||
|
new_root.children[index] = self.root_node
|
||||||
|
self.root_node = new_root
|
||||||
|
|
||||||
|
self.origin = (
|
||||||
|
self.origin[0] - (x >= 0) * 2 + 1,
|
||||||
|
self.origin[1] - (y >= 0) * 2 + 1,
|
||||||
|
self.origin[2] - (z >= 0) * 2 + 1
|
||||||
|
)
|
||||||
|
|
||||||
|
def _insert(self, node, x, y, z, size):
|
||||||
|
while not size == 1:
|
||||||
|
index, x, y, z = self._get_child_index(x, y, z, size)
|
||||||
|
|
||||||
|
if node.children[index] is None:
|
||||||
|
node.children[index] = Node()
|
||||||
|
|
||||||
|
size //= 2
|
||||||
|
|
||||||
|
node.leaf = True
|
||||||
|
|
||||||
|
def insert(self, x, y, z):
|
||||||
|
# move origin if necessary
|
||||||
|
while not (0 <= x < 2 ** 30 and 0 <= y < 2 ** 30 and 0 <= z < 2 ** 30):
|
||||||
|
self._extend_tree(x, y, z)
|
||||||
|
|
||||||
|
x, y, z = (
|
||||||
|
x - self.origin[0],
|
||||||
|
y - self.origin[1],
|
||||||
|
z - self.origin[2]
|
||||||
|
)
|
||||||
|
|
||||||
|
self._insert(self.root_node, x, y, z, 2 ** 30)
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
deprecated
|
Loading…
Reference in a new issue