Compare commits

..

6 commits
main ... dev

4 changed files with 185 additions and 2 deletions

View file

@ -7,10 +7,10 @@ With this module, you can store data in files easyly.
import os
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:
"""
This class is not safe to use!

93
infinite_matrix.py Normal file
View 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
View 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
View file

@ -0,0 +1 @@
deprecated