wobbl_tools/infinite_matrix.py

93 lines
No EOL
3.5 KiB
Python

#!/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))