'Python Matrix Multiplication receives Error "can't multiply sequence by non-int of type 'list'"
I want to print out
P_parallel = S_parallel_matrix * T_parallel_matrix * SH_xy * Rot_n_up_t * translation_matrix
When I run the code, I get the following error:
line 182, in perspective_projection
P_parallel = S_parallel_matrix * T_parallel_matrix
TypeError: can't multiply sequence by non-int of type 'list'
I tried to split my multiplication, so I first tried to multiply:
P_parallel = S_parallel_matrix * T_parallel_matrix
Then I directly got the same error again and it was highlighting the T_parallel_matrix. So I know that it is because of the T_parallel_matrix.
This is my main.py code:
from __future__ import print_function, division, unicode_literals, absolute_import
import numpy as np
from mat4x4 import Mat4x4
from vec3 import Vec3
# Function perspective_projection
def perspective_projection(P, up, normal, v, l, r, b, t, n, f):
# 4x4 Translation-Matrix T(-Px, -Py, -Pz)
translation_matrix = [[1, 0, 0, (-P.x)],
[0, 1, 0, (-P.y)],
[0, 0, 1, (-P.z)],
[0, 0, 0, 1]
]
print('Translationsmatrix: ' + str(translation_matrix))
# return
# Conversion of viewing volume to standard orientation z' = n (normal of the image plane) 1x3 matrix
z_strich = normal
print('z_strich: ' + str(z_strich))
# return
# Calculation x' = up X z' / |up X z'|
x_strich = up.cross(z_strich) / abs(up.cross(z_strich))
print('x_strich: ' + str(x_strich))
# return
# Calculation y' = z' X x'
y_strich = z_strich.cross(x_strich)
print('y_strich: ' + str(y_strich))
# return
# 4x4 Rotationmatrix R(n, up)
Rot_n_up = [[x_strich.x, y_strich.x, z_strich.x, 0],
[x_strich.y, y_strich.y, z_strich.y, 0],
[x_strich.z, y_strich.z, z_strich.z, 0],
[0, 0, 0, 1]
]
print('Rotationsmatrix R(n, up): ' + str(Rot_n_up))
# return
# Inverse Rotationmatrix R(n, up)-1 = R(n, up)T
Rot_n_up_i = [[x_strich.x, x_strich.y, x_strich.z, 0],
[y_strich.x, y_strich.y, y_strich.z, 0],
[z_strich.x, z_strich.y, z_strich.z, 0],
[0, 0, 0, 1]
]
print('Inverse Rotationmatrix R(n, up)-1: ' + str(Rot_n_up_i))
# return
# Inverse Rotationmatrix R(n, up)T = R(n, up)-1
Rot_n_up_t = np.linalg.inv(Rot_n_up_i)
print('Inverse Rotationmatrix R(n, up)T: ' + str(Rot_n_up_t))
# Standard orientation: R(n, up)T * T(-Px, -Py, -Pz)
standard_orientation = Rot_n_up_t * translation_matrix
print('Standard orientation: ' + str(standard_orientation))
# return
# Transfer to the canonical visual volume
# SHxy = 4x4 Matrix -> SHxy * v = (0 0 vz) <- 1x3 Matrix
sh_x = -(v.x / v.z)
sh_y = -(v.y / v.z)
SH_xy = [[1, 0, sh_x, 0],
[0, 1, sh_y, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]
]
print('SHx: ' + str(sh_x))
print('SHy: ' + str(sh_y))
print('SHxy: ' + str(SH_xy))
# return
# Sight volume is shifted so that the center is at the origin
T_parallel = ((-(r + l) / 2), (-(t + b) / 2), (-(n + f) / 2))
T_parallel_matrix = [[1, 0, 0, (-(r + l) / 2)],
[0, 1, 0, (-(t + b) / 2)],
[0, 0, 1, (-(n + f) / 2)],
[0, 0, 0, 1]
]
# T_parallel_matrix = Mat4x4(a11=1, a12=0, a13=0, a14=3, a21=0, a22=1, a23=0, a24=3, a31=0, a32=0, a33=1, a34=3, a41=0, a42=0, a43=0, a44=1)
print("Tparallel: " + (str(T_parallel)))
print("Tparallel Matrix: " + (str(T_parallel_matrix)))
# return
# Convert visible volume to canonical visible volume
S_parallel = ((2 / (r - l)), (2 / (r - b)), (2 / (f - n)))
S_parallel_matrix = [[(2 / (r - l)), 0, 0, 0],
[0, (2 / (r - b)), 0, 0],
[0, 0, (2 / (f - n)), 0],
[0, 0, 0, 1]
]
# S_parallel_matrix = Mat4x4((2 / (r - l)), 0, 0, 0, 0, (2 / (r - b)), 0, 0, 0, 0, (2 / (f - n)), 0, 0, 0, 0, 1)
print('Sparallel: ' + str(S_parallel))
print("Sparallel Matrix: " + (str(S_parallel_matrix)))
# return
# Total transformation sequence
# P_parallel = S_parallel_matrix * T_parallel_matrix * SH_xy * Rot_n_up_t * translation_matrix
P_parallel = S_parallel_matrix * T_parallel_matrix
print('Pparallel: ' + str(P_parallel))
# return
if __name__ == '__main__':
# Note: The following values are test values
P = Vec3(x=-1, y=-1, z=1) # P = Camera Position
up = Vec3(x=0, y=1, z=0) # up = Up Vector
normal = Vec3(x=0, y=0, z=-1) # normal = Normal of the direction of view
v = (Vec3(x=0, y=0, z=0) - P) # v = View
l = -4 # l = left
r = 2 # r = right
b = -3 # b = bottom
t = 2 # t = top
n = -1 # n = near
f = -99 # f = far
perspective_projection(P, up, normal, v, l, r, b, t, n, f)
When I run it, my output is the following:
Translationmatrix: [[1, 0, 0, 1], [0, 1, 0, 1], [0, 0, 1, -1], [0, 0, 0, 1]]
z_strich: (0, 0, -1)
x_strich: (-1, 0, 0)
y_strich: (0, 1, 0)
Rotationsmatrix R(n, up): [[-1.0, 0.0, 0, 0], [0.0, 1.0, 0, 0], [0.0, 0.0, -1, 0],
[0, 0, 0, 1]]
Inverse Rotationmatrix R(n, up)-1: [[-1.0, 0.0, 0.0, 0], [0.0, 1.0, 0.0, 0], [0, 0,
-1, 0], [0, 0, 0, 1]]
Inverse Rotationmatrix R(n, up)T: [[-1. -0. -0. -0.]
[ 0. 1. 0. 0.]
[-0. -0. -1. -0.]
[ 0. 0. 0. 1.]]
Standard orientation: [[-1. -0. -0. -0.]
[ 0. 1. 0. 0.]
[-0. -0. -1. 0.]
[ 0. 0. 0. 1.]]
SHx: 1.0
SHy: 1.0
SHxy: [[1, 0, 1.0, 0], [0, 1, 1.0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
Tparallel: (1.0, 0.5, 50.0)
Tparallel Matrix: [[1, 0, 0, 1.0], [0, 1, 0, 0.5], [0, 0, 1, 50.0], [0, 0, 0, 1]]
Sparallel: (0.3333333333333333, 0.4, -0.02040816326530612)
Sparallel Matrix: [[0.3333333333333333, 0, 0, 0], [0, 0.4, 0, 0], [0, 0,
-0.02040816326530612, 0], [0, 0, 0, 1]]
So you can see, that everything works completely fine - even S_parallel_matrix which has also some calculations in it (just like T_parallel_matrix which doesn't work). I also tried to put the matrix like this:
T_parallel_matrix = Mat4x4(a11=1, a12=0, a13=0, a14=3, a21=0, a22=1, a23=0, a24=3, a31=0, a32=0, a33=1, a34=3, a41=0, a42=0, a43=0, a44=1)
But when I run it, I get this error:
line 159, in perspective_projection
T_parallel_matrix = Mat4x4(a11=1, a12=0, a13=0, a14=3, a21=0, a22=1, a23=0, a24=3, a31=0, a32=0, a33=1, a34=3, a41=0, a42=0, a43=0, a44=1)
mat4x4.py", line 12, in __init__
self.a11 = a11, self.a12 = a12, self.a13 = a13, self.a14 = a14
TypeError: cannot unpack non-iterable int object
I believe that my mat4x4 class is somehow incorrect, but I'm not quite sure what the problem causes.
Can somebody explain why I get the first error (non int type) only with T_parallel_matrix?
This is my mat4x4.py with the Mat4x4 Class:
from __future__ import annotations
class Mat4x4:
def __init__(self,
a11: float, a12: float, a13: float, a14: float,
a21: float, a22: float, a23: float, a24: float,
a31: float, a32: float, a33: float, a34: float,
a41: float, a42: float, a43: float, a44: float,
):
self.a11 = a11, self.a12 = a12, self.a13 = a13, self.a14 = a14
self.a21 = a21, self.a22 = a22, self.a23 = a23, self.a24 = a24
self.a31 = a31, self.a32 = a32, self.a33 = a33, self.a34 = a34
self.a41 = a41, self.a42 = a42, self.a43 = a43, self.a44 = a44
# Matrix multiplication
def __mul__(self, other: Mat4x4) -> Mat4x4:
return Mat4x4(
self.a11 * other.a11 + self.a12 * other.a21 + self.a13 * other.a31 + self.a14 * other.a41, # a11
self.a11 * other.a12 + self.a12 * other.a22 + self.a13 * other.a32 + self.a14 * other.a42, # a12
self.a11 * other.a13 + self.a12 * other.a23 + self.a13 * other.a33 + self.a14 * other.a43, # a13
self.a11 * other.a14 + self.a12 * other.a24 + self.a13 * other.a34 + self.a14 * other.a44, # a14
self.a21 * other.a11 + self.a22 * other.a12 + self.a23 * other.a13 + self.a24 * other.a14, # a21
self.a21 * other.a21 + self.a22 * other.a22 + self.a23 * other.a23 + self.a24 * other.a24, # a22
self.a21 * other.a31 + self.a22 * other.a32 + self.a23 * other.a33 + self.a24 * other.a34, # a23
self.a21 * other.a41 + self.a22 * other.a42 + self.a23 * other.a43 + self.a24 * other.a44, # a24
self.a31 * other.a11 + self.a32 * other.a12 + self.a33 * other.a13 + self.a34 * other.a14, # a31
self.a31 * other.a21 + self.a32 * other.a22 + self.a33 * other.a23 + self.a34 * other.a24, # a32
self.a31 * other.a31 + self.a32 * other.a32 + self.a33 * other.a33 + self.a34 * other.a34, # a33
self.a31 * other.a41 + self.a32 * other.a42 + self.a33 * other.a43 + self.a34 * other.a44, # a34
self.a41 * other.a11 + self.a42 * other.a12 + self.a43 * other.a13 + self.a44 * other.a14, # a41
self.a41 * other.a21 + self.a42 * other.a22 + self.a43 * other.a23 + self.a44 * other.a24, # a42
self.a41 * other.a31 + self.a42 * other.a32 + self.a43 * other.a33 + self.a44 * other.a34, # a43
self.a41 * other.a41 + self.a42 * other.a42 + self.a43 * other.a43 + self.a44 * other.a44, # a44
)
# Add
def __add__(self, other: Mat4x4) -> Mat4x4:
return Mat4x4(
self.a11 + other.a11, # a11
self.a12 + other.a12, # a12
self.a13 + other.a13, # a13
self.a14 + other.a14, # a14
self.a21 + other.a21, # a21
self.a22 + other.a22, # a22
self.a23 + other.a23, # a23
self.a24 + other.a24, # a24
self.a31 + other.a31, # a31
self.a32 + other.a32, # a32
self.a33 + other.a33, # a33
self.a34 + other.a34, # a34
self.a41 + other.a41, # a41
self.a42 + other.a42, # a42
self.a43 + other.a43, # a43
self.a44 + other.a44, # a44
)
# Subtract
def __sub__(self, other: Mat4x4) -> Mat4x4:
return Mat4x4(
self.a11 - other.a11, # a11
self.a12 - other.a12, # a12
self.a13 - other.a13, # a13
self.a14 - other.a14, # a14
self.a21 - other.a21, # a21
self.a22 - other.a22, # a22
self.a23 - other.a23, # a23
self.a24 - other.a24, # a24
self.a31 - other.a31, # a31
self.a32 - other.a32, # a32
self.a33 - other.a33, # a33
self.a34 - other.a34, # a34
self.a41 - other.a41, # a41
self.a42 - other.a42, # a42
self.a43 - other.a43, # a43
self.a44 - other.a44, # a44
)
# Not Equal
def __ne__(self) -> Mat4x4:
return Mat4x4(
-self.a11, # a11
-self.a12, # a12
-self.a13, # a13
-self.a14, # a14
-self.a21, # a21
-self.a22, # a22
-self.a23, # a23
-self.a24, # a24
-self.a31, # a31
-self.a32, # a32
-self.a33, # a33
-self.a34, # a34
-self.a41, # a41
-self.a42, # a42
-self.a43, # a43
-self.a44, # a44
)
# Convert to string
def __str__(self) -> str:
return (
f'{self.a11} {self.a12} {self.a13} {self.a14}\n' +
f'{self.a21} {self.a22} {self.a23} {self.a24}\n' +
f'{self.a31} {self.a32} {self.a33} {self.a34}\n' +
f'{self.a41} {self.a42} {self.a43} {self.a44}'
)
(If neccessary I can add the code for Vec3, but I think the problem ist with the mat4x4 class. )
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
