Changed matrix object names to be more natural. Fixed a bug in the matrix projection math.

This commit is contained in:
2020-07-15 09:12:09 -05:00
parent 34f5917359
commit 4ef62ab916
3 changed files with 127 additions and 85 deletions
+59 -15
View File
@@ -1,38 +1,82 @@
import vectors
import math
from vectors import Vector3d, Vector4d
class Matrix4x4:
def __init__(self, row0, row1, row2, row3):
if not isinstance(row0, vectors.Vector4d):
raise ValueError("Row must be a Vector4d object.", row0)
if not isinstance(row1, vectors.Vector4d):
def __init__(self, row1, row2, row3, row4):
if not isinstance(row1, Vector4d):
raise ValueError("Row must be a Vector4d object.", row1)
if not isinstance(row2, vectors.Vector4d):
if not isinstance(row2, Vector4d):
raise ValueError("Row must be a Vector4d object.", row2)
if not isinstance(row3, vectors.Vector4d):
if not isinstance(row3, Vector4d):
raise ValueError("Row must be a Vector4d object.", row3)
if not isinstance(row4, Vector4d):
raise ValueError("Row must be a Vector4d object.", row4)
self.row0 = row0
self.row1 = row1
self.row2 = row2
self.row3 = row3
self.row4 = row4
def multiply_3d(self, vector3d):
x = vector3d.x * self.row0.x + vector3d.y * self.row1.x + vector3d.z * self.row2.x + self.row3.x
y = vector3d.x * self.row0.y + vector3d.y * self.row1.y + vector3d.z * self.row2.y + self.row3.y
z = vector3d.x * self.row0.z + vector3d.y * self.row1.z + vector3d.z * self.row2.z + self.row3.z
w = vector3d.x * self.row0.w + vector3d.y * self.row1.w + vector3d.z * self.row2.w + self.row3.w
x = vector3d.x * self.row1.x + vector3d.y * self.row2.x + vector3d.z * self.row3.x + self.row4.x
y = vector3d.x * self.row1.y + vector3d.y * self.row2.y + vector3d.z * self.row3.y + self.row4.y
z = vector3d.x * self.row1.z + vector3d.y * self.row2.z + vector3d.z * self.row3.z + self.row4.z
w = vector3d.x * self.row1.w + vector3d.y * self.row2.w + vector3d.z * self.row3.w + self.row4.w
if w != 0:
x /= w
y /= w
z /= w
return vectors.Vector3d(x, y, z)
return Vector3d(x, y, z)
def get_projection_matrix(fov_degrees, aspect_ratio, near_plane, far_plane):
fov_rad = 1 / math.tan(fov_degrees * 0.5 / 180.0 * math.pi)
row1 = Vector4d(aspect_ratio * fov_rad, 0, 0, 0)
row2 = Vector4d(0, fov_rad, 0, 0)
row3 = Vector4d(0, 0, far_plane / (far_plane - near_plane), 1.0)
row4 = Vector4d(0, 0, -far_plane * near_plane / (far_plane - near_plane), 0)
return Matrix4x4(row1, row2, row3, row4)
def get_identity_matrix():
row1 = Vector4d(1, 0, 0, 0)
row2 = Vector4d(0, 1, 0, 0)
row3 = Vector4d(0, 0, 1, 0)
row4 = Vector4d(0, 0, 0, 1)
return Matrix4x4(row1, row2, row3, row4)
def get_y_rotation_matrix(angle_rad):
row1 = Vector4d(math.cos(angle_rad), 0, math.sin(angle_rad), 0)
row2 = Vector4d(0, 1, 0, 0)
row3 = Vector4d(-math.sin(angle_rad), 0, math.cos(angle_rad), 0)
row4 = Vector4d(0, 0, 0, 1)
return Matrix4x4(row1, row2, row3, row4)
def get_z_rotation_matrix(angle_rad):
row1 = Vector4d(math.cos(angle_rad), math.sin(angle_rad), 0, 0)
row2 = Vector4d(-math.sin(angle_rad), math.cos(angle_rad), 0, 0)
row3 = Vector4d(0, 0, 0, 0)
row4 = Vector4d(0, 0, 1, 0)
return Matrix4x4(row1, row2, row3, row4)
def get_x_rotation_matrix(angle_rad):
row1 = Vector4d(1, 0, 0, 0)
row2 = Vector4d(0, math.cos(angle_rad), math.sin(angle_rad), 0)
row3 = Vector4d(0, -math.sin(angle_rad), math.cos(angle_rad), 0)
row4 = Vector4d(0, 0, 0, 1)
return Matrix4x4(row1, row2, row3, row4)
class Matrix3x3:
def __init__(self, row0, row1, row2):
self.row0 = row0
def __init__(self, row1, row2, row3):
self.row1 = row1
self.row2 = row2
self.row3 = row3