| |
|
| | import copy |
| | import ctypes |
| | import math |
| |
|
| | def copy_matrix(matrix): |
| | return copy.deepcopy(matrix) |
| |
|
| | clean_matrix = [[0.0 for x in range(4)] for x in range(4)] |
| | identity_matrix = copy_matrix(clean_matrix) |
| |
|
| | identity_matrix[0][0] = 1.0 |
| | identity_matrix[1][1] = 1.0 |
| | identity_matrix[2][2] = 1.0 |
| | identity_matrix[3][3] = 1.0 |
| |
|
| | def multiply_matrices(x_matrix, y_matrix): |
| | result_matrix = copy_matrix(clean_matrix) |
| | |
| | for i in range(4): |
| | for j in range(4): |
| | result_matrix[i][j] = \ |
| | (x_matrix[0][j] * y_matrix[i][0]) + \ |
| | (x_matrix[1][j] * y_matrix[i][1]) + \ |
| | (x_matrix[2][j] * y_matrix[i][2]) + \ |
| | (x_matrix[3][j] * y_matrix[i][3]) |
| |
|
| | return result_matrix |
| |
|
| | class Matrix: |
| | def __init__(self, base = None): |
| | if type(base) == Matrix: self.data = copy_matrix(base.data) |
| | elif type(base) == list: self.data = copy_matrix(base) |
| | else: self.data = copy_matrix(clean_matrix) |
| | |
| | def load_identity(self): |
| | self.data = copy_matrix(identity_matrix) |
| | |
| | def __mul__(self, matrix): |
| | return Matrix(multiply_matrices(self.data, matrix.data)) |
| |
|
| | def __imul__(self, matrix): |
| | self.data = multiply_matrices(self.data, matrix.data) |
| |
|
| | def scale(self, x, y, z): |
| | for i in range(4): self.data[0][i] *= x |
| | for i in range(4): self.data[1][i] *= y |
| | for i in range(4): self.data[2][i] *= z |
| |
|
| | def translate(self, x, y, z): |
| | for i in range(4): |
| | self.data[3][i] = self.data[3][i] + (self.data[0][i] * x + self.data[1][i] * y + self.data[2][i] * z) |
| | |
| | def rotate(self, angle, x, y, z): |
| | magnitude = math.sqrt(x * x + y * y + z * z) |
| | |
| | x /= -magnitude |
| | y /= -magnitude |
| | z /= -magnitude |
| | |
| | sin_angle = math.sin(angle) |
| | cos_angle = math.cos(angle) |
| | one_minus_cos = 1.0 - cos_angle |
| | |
| | xx = x * x |
| | yy = y * y |
| | zz = z * z |
| | |
| | xy = x * y |
| | yz = y * z |
| | zx = z * x |
| | |
| | xs = x * sin_angle |
| | ys = y * sin_angle |
| | zs = z * sin_angle |
| | |
| | rotation_matrix = copy_matrix(clean_matrix) |
| | |
| | rotation_matrix[0][0] = (one_minus_cos * xx) + cos_angle |
| | rotation_matrix[0][1] = (one_minus_cos * xy) - zs |
| | rotation_matrix[0][2] = (one_minus_cos * zx) + ys |
| | |
| | rotation_matrix[1][0] = (one_minus_cos * xy) + zs |
| | rotation_matrix[1][1] = (one_minus_cos * yy) + cos_angle |
| | rotation_matrix[1][2] = (one_minus_cos * yz) - xs |
| | |
| | rotation_matrix[2][0] = (one_minus_cos * zx) - ys |
| | rotation_matrix[2][1] = (one_minus_cos * yz) + xs |
| | rotation_matrix[2][2] = (one_minus_cos * zz) + cos_angle |
| | |
| | rotation_matrix[3][3] = 1.0 |
| | self.data = multiply_matrices(self.data, rotation_matrix) |
| | |
| | def rotate_2d(self, x, y): |
| | self.rotate(x, 0, 1.0, 0) |
| | self.rotate(-y, math.cos(x), 0, math.sin(x)) |
| | |
| | def frustum(self, left, right, bottom, top, near, far): |
| | deltax = right - left |
| | deltay = top - bottom |
| | deltaz = far - near |
| | |
| | frustum_matrix = copy_matrix(clean_matrix) |
| | |
| | frustum_matrix[0][0] = 2 * near / deltax |
| | frustum_matrix[1][1] = 2 * near / deltay |
| | |
| | frustum_matrix[2][0] = (right + left) / deltax |
| | frustum_matrix[2][1] = (top + bottom) / deltay |
| | frustum_matrix[2][2] = -(near + far) / deltaz |
| | |
| | frustum_matrix[2][3] = -1.0 |
| | frustum_matrix[3][2] = -2 * near * far / deltaz |
| | |
| | self.data = multiply_matrices(self.data, frustum_matrix) |
| | |
| | def perspective(self, fovy, aspect, near, far): |
| | frustum_y = math.tan(math.radians(fovy) / 2) |
| | frustum_x = frustum_y * aspect |
| | |
| | self.frustum(-frustum_x * near, frustum_x * near, -frustum_y * near, frustum_y * near, near, far) |
| | |
| | def orthographic(self, left, right, bottom, top, near, far): |
| | deltax = right - left |
| | deltay = top - bottom |
| | deltaz = far - near |
| | |
| | orthographic_matrix = copy_matrix(identity_matrix) |
| | |
| | orthographic_matrix[0][0] = 2.0 / deltax |
| | orthographic_matrix[3][0] = -(right + left) / deltax |
| | |
| | orthographic_matrix[1][1] = 2.0 / deltay |
| | orthographic_matrix[3][1] = -(top + bottom) / deltay |
| | |
| | orthographic_matrix[2][2] = 2.0 / deltax |
| | orthographic_matrix[3][2] = -(near + far) / deltaz |
| | |
| | self.data = multiply_matrices(self.data, orthographic_matrix) |
| |
|