Fix bug in matrix inversion code relating to upper triangles causing some matrixes to fail to invert and hiding some textures.
This commit is contained in:
parent
6e76c25e95
commit
96a99f6f74
@ -319,6 +319,14 @@ class Matrix:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def inverse(self) -> "Matrix":
|
def inverse(self) -> "Matrix":
|
||||||
|
try:
|
||||||
|
return self.__inverse_impl()
|
||||||
|
except ZeroDivisionError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
raise ZeroDivisionError(f"Matrix({self}) cannot be inverted!")
|
||||||
|
|
||||||
|
def __inverse_impl(self) -> "Matrix":
|
||||||
# Use gauss-jordan eliminiation to invert the matrix.
|
# Use gauss-jordan eliminiation to invert the matrix.
|
||||||
size = 4
|
size = 4
|
||||||
m = [
|
m = [
|
||||||
@ -329,36 +337,44 @@ class Matrix:
|
|||||||
]
|
]
|
||||||
inverse: List[List[float]] = [[1 if row == col else 0 for col in range(size)] for row in range(size)]
|
inverse: List[List[float]] = [[1 if row == col else 0 for col in range(size)] for row in range(size)]
|
||||||
|
|
||||||
# First, get upper triangle of the matrix.
|
|
||||||
for col in range(size):
|
for col in range(size):
|
||||||
|
# First, get upper triangle of the matrix.
|
||||||
if col < size - 1:
|
if col < size - 1:
|
||||||
numbers = [m[row][col] for row in range(col, size)]
|
numbers = [m[row][col] for row in range(col, size)]
|
||||||
if all(n == 0 for n in numbers):
|
if all(n == 0 for n in numbers):
|
||||||
print("HOO!")
|
|
||||||
raise ZeroDivisionError(f"Matrix({self}) cannot be inverted!")
|
raise ZeroDivisionError(f"Matrix({self}) cannot be inverted!")
|
||||||
|
|
||||||
# Reorder the matrix until all nonzero numbers are at the top.
|
# Reorder the matrix until all nonzero numbers are at the top.
|
||||||
for row in range(col, size - 1):
|
nonzeros_m = []
|
||||||
# First, make sure all non-zero values are at the top.
|
nonzeros_inverse = []
|
||||||
|
zeros_m = []
|
||||||
|
zeros_inverse = []
|
||||||
|
|
||||||
|
for row in range(size):
|
||||||
nrow = row - col
|
nrow = row - col
|
||||||
|
if nrow < 0:
|
||||||
|
# This is above the current part of the triangle, just
|
||||||
|
# include it as-is without reordering.
|
||||||
|
nonzeros_m.append(m[row])
|
||||||
|
nonzeros_inverse.append(inverse[row])
|
||||||
|
continue
|
||||||
|
|
||||||
if numbers[nrow] == 0:
|
if numbers[nrow] == 0:
|
||||||
# Put this at the end.
|
# Put this at the end.
|
||||||
numbers = [
|
zeros_m.append(m[row])
|
||||||
*numbers[:nrow],
|
zeros_inverse.append(inverse[row])
|
||||||
*numbers[(nrow + 1):],
|
else:
|
||||||
numbers[nrow],
|
nonzeros_m.append(m[row])
|
||||||
]
|
nonzeros_inverse.append(inverse[row])
|
||||||
m = [
|
|
||||||
*m[:row],
|
m = [
|
||||||
*m[(row + 1):],
|
*nonzeros_m,
|
||||||
m[row],
|
*zeros_m,
|
||||||
]
|
]
|
||||||
inverse = [
|
inverse = [
|
||||||
*inverse[:row],
|
*nonzeros_inverse,
|
||||||
*inverse[(row + 1):],
|
*zeros_inverse,
|
||||||
inverse[row],
|
]
|
||||||
]
|
|
||||||
row += 1
|
|
||||||
|
|
||||||
# Now, figure out what multiplier we need to make every
|
# Now, figure out what multiplier we need to make every
|
||||||
# other entry zero.
|
# other entry zero.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user