'How to get a 4x4 translation matrix from a vector in python
I want to get a 4x4 translation matrix from a vec3 in Python. I don't know how I can do that correctly.
Can someboday explain what exactly needs to be done and how I can achieve this?
This is what I mean:
So basically the vector of T should become a 4x4 Matrix (like in the picture)
This is my code and the formula for the translation matrix:
# 4x4 Translations-Matrix T(-Px, -Py, -Pz) - needs to be 4x4 matrix
translation_matrix = (-P.x, -P.y, -P.z)
My Mat4x4 looks like this:
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}'
)
And this is my code for Vec3:
import math
import numpy as np
class Vec3:
def __init__(self, x: float, y: float, z: float):
self.x = x
self.y = y
self.z = z
# Addition
def __add__(self, other):
return Vec3(self.x + other.x, self.y + other.y, self.z + other.z)
def __radd__(self, other):
# other = self.convert2Vec3D(other)
return self.__add__(other)
# Subtraktion
def __rsub__(self, other):
# other = self.convert2Vec3D(other)
return other.__sub__(self)
def __sub__(self, other):
# other = self.convert2Vec3D(other)
return Vec3(self.x - other.x, self.y - other.y, self.z - other.z)
# Multiplikation
def __mul__(self, other):
return Vec3(self.x * other.x + self.y * other.y + self.z * other.z)
def __rmul__(self, other):
return self.__rmul__(self, other)
# Division
def __truediv__(self, other):
return Vec3(self.x / other.x, self.y / other.y, self.z / other.z)
# AttributeError: 'float' object has no attribute 'x'
def __rtruediv__(self, other):
# other = self.convert2Vec3D(other)
return other.__rtruediv__(self)
# Kreuzprodukt
def cross(self, other):
x1, y1, z1 = self.x, self.y, self.z
x2, y2, z2 = other.x, other.y, other.z
return Vec3(y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2)
def __str__(self):
return '(%g, %g, %g)' % (self.x, self.y, self.z)
# Absoluter Wert
def __abs__(self):
absValue = math.sqrt(self.x ** 2 + self.y ** 2 + self.z ** 2)
return Vec3(absValue, absValue, absValue)
I already tried to do some things like this
# translation_matrix = Mat4x4(a11=-P.x, a12=-P.y, a13=-P.z, a14=-P.x,
# a21=-P.x, a22=-P.y, a23=-P.z, a24=-P.x,
# a31=P.x, a32=P.y, a33=P.z, a34=P.x,
# a41=-P.x, a42=-P.y, a43=P.z, a44=-P.x)
But this approach doesn't seem right. So my question is: How can I properly get a 4x4 Matrix out of a Vector? It only needs to be printed out as a string, so I don't need it for drawing or something like that.
Solution 1:[1]
Assuming that this is the transformation you are trying to do:
The easiest to achieve that would be something along the lines of:
import numpy as np
v = np.array((-1, -1, 1))
T = np.identity(n=4)
T[0:3,3] = -v
This yields what I think you want:
>>> T
array([[ 1., 0., 0., 1.],
[ 0., 1., 0., 1.],
[ 0., 0., 1., -1.],
[ 0., 0., 0., 1.]])
All the magic happens in the last line, T[0:3,3] = -v, where you are assigning the three matrix elements: T[0,3]=-v[0], T[1,3]=-v[1], and T[2,3]=-v[2]. If you want to implement something similar within your own framework, you will need to use per-element assignments because your matrix is not a numpy ndarray. That said, I'd urge that you use ndarrays, they're much faster, more versatile and will save you from writing a lot of boilerplate code.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Andrej Prsa |
