Cleaned up the proof of concept code to be more object oriented. Functionally, some mouse and key bindings were added to make the demo a bit more interactive.
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
import window
|
import window
|
||||||
import math
|
import math
|
||||||
import copy
|
import copy
|
||||||
|
from matrix import Matrix4x4, Matrix3x3
|
||||||
|
from vectors import Vector4d, Vector3d, Vector2d
|
||||||
|
|
||||||
ui = window.Window(600, 600)
|
ui = window.Window(600, 600)
|
||||||
near_plane = 0.1
|
near_plane = 0.1
|
||||||
@@ -33,97 +35,112 @@ tris = [
|
|||||||
[[ 1.0, 0.0, 1.0], [0.0, 0.0, 0.0], [1.0, 0.0, 0.0 ]]
|
[[ 1.0, 0.0, 1.0], [0.0, 0.0, 0.0], [1.0, 0.0, 0.0 ]]
|
||||||
]
|
]
|
||||||
|
|
||||||
def matric_mul(d_vector, transform_mat):
|
|
||||||
out_matrix = []
|
|
||||||
out_matrix.append(d_vector[0] * transform_mat[0][0] + d_vector[1] * transform_mat[1][0] + d_vector[2] * transform_mat[2][0] + transform_mat[3][0]) # x
|
|
||||||
out_matrix.append(d_vector[0] * transform_mat[0][1] + d_vector[1] * transform_mat[1][1] + d_vector[2] * transform_mat[2][1] + transform_mat[3][1]) # y
|
|
||||||
out_matrix.append(d_vector[0] * transform_mat[0][2] + d_vector[1] * transform_mat[1][2] + d_vector[2] * transform_mat[2][2] + transform_mat[3][2]) # z
|
|
||||||
# 4th row
|
|
||||||
w = d_vector[0] * transform_mat[0][3] + d_vector[1] * transform_mat[1][3] + d_vector[2] * transform_mat[2][3] + transform_mat[3][3]
|
|
||||||
|
|
||||||
if w != 0:
|
|
||||||
out_matrix[0] /= w
|
|
||||||
out_matrix[1] /= w
|
|
||||||
out_matrix[2] /= w
|
|
||||||
|
|
||||||
return out_matrix
|
|
||||||
|
|
||||||
def make_matrix(row1, row2, row3, row4):
|
|
||||||
mat = []
|
|
||||||
mat.append([])
|
|
||||||
mat[0].append([row1[0], row1[1], row1[2], row1[3]])
|
|
||||||
mat.append([])
|
|
||||||
mat[1].append([row2[0], row2[1], row2[2], row2[3]])
|
|
||||||
mat.append([])
|
|
||||||
mat[2].append([row3[0], row3[1], row3[2], row3[3]])
|
|
||||||
mat.append([])
|
|
||||||
mat[3].append([row4[0], row4[1], row4[2], row4[3]])
|
|
||||||
|
|
||||||
return mat
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
ui.thetax = 1
|
||||||
|
ui.window.bind('<Left>', left)
|
||||||
|
ui.window.bind('<Right>', right)
|
||||||
|
ui.window.bind('<ButtonPress-1>', mouse_start)
|
||||||
|
ui.window.bind('<B1-Motion>', mouse_end)
|
||||||
|
ui.canvas.old_coords = None
|
||||||
ui.window.after(0, draw_scene)
|
ui.window.after(0, draw_scene)
|
||||||
ui.show()
|
ui.show()
|
||||||
|
|
||||||
|
def left(event):
|
||||||
|
ui.theta -= .01
|
||||||
|
|
||||||
|
def right(event):
|
||||||
|
ui.theta += .01
|
||||||
|
|
||||||
|
def mouse_start(event):
|
||||||
|
#x, y =
|
||||||
|
ui.canvas.old_coords = event.x, event.y #x, y
|
||||||
|
|
||||||
|
def mouse_end(event):
|
||||||
|
x, y = ui.canvas.old_coords[0] - event.x, ui.canvas.old_coords[1] - event.y
|
||||||
|
if x < 0:
|
||||||
|
ui.theta += .01
|
||||||
|
else:
|
||||||
|
ui.theta -= .01
|
||||||
|
|
||||||
|
print(ui.theta)
|
||||||
|
|
||||||
|
if y < 0:
|
||||||
|
ui.thetax += .01
|
||||||
|
else:
|
||||||
|
ui.thetax -= .01
|
||||||
|
#ui.theta += x / ui.width
|
||||||
|
|
||||||
def draw_scene():
|
def draw_scene():
|
||||||
ui.canvas.delete("all")
|
ui.canvas.delete("all")
|
||||||
ui.theta += .01
|
#ui.theta += .01 # scaling factor
|
||||||
projection_matrix = []
|
|
||||||
rotation_matrix_z = []
|
|
||||||
rotation_matrix_x = []
|
|
||||||
aspect_ratio = ui.height / ui.width
|
aspect_ratio = ui.height / ui.width
|
||||||
fov_rad = ui.theta / math.tan(fov * 0.5 / 180.0 * math.pi)
|
fov_rad = ui.theta / math.tan(fov * 0.5 / 180.0 * math.pi)
|
||||||
|
|
||||||
projection_matrix.append([aspect_ratio * fov_rad, 0, 0, 0])
|
row0 = Vector4d(aspect_ratio * fov_rad, 0, 0, 0)
|
||||||
projection_matrix.append([0, fov_rad, 0, 0])
|
row1 = Vector4d(0, fov_rad, 0, 0)
|
||||||
projection_matrix.append([0, 0, far_plane / (far_plane - near_plane), 1.0])
|
row2 = Vector4d(0, 0, far_plane / (far_plane - near_plane), 1.0)
|
||||||
projection_matrix.append([0, 0, -far_plane * near_plane / (far_plane - near_plane), 0])
|
row3 = Vector4d(0, 0, -far_plane * near_plane / (far_plane - near_plane), 0)
|
||||||
|
|
||||||
rotation_matrix_z.append([math.cos(ui.theta), math.sin(ui.theta), 0, 0])
|
projection_matrix = Matrix4x4(row0, row1, row2, row3)
|
||||||
rotation_matrix_z.append([-math.sin(ui.theta), math.cos(ui.theta), 0, 0])
|
|
||||||
rotation_matrix_z.append([0, 0, 1, 0])
|
|
||||||
rotation_matrix_z.append([0, 0, 0, 1])
|
|
||||||
#--------------------------------------------
|
|
||||||
rotation_matrix_x.append([1, 0, 0, 0])
|
|
||||||
rotation_matrix_x.append([0, math.cos(ui.theta * 0.5), math.sin(ui.theta * 0.5), 0])
|
|
||||||
rotation_matrix_x.append([0, -math.sin(ui.theta * 0.5), math.cos(ui.theta * 0.5), 0])
|
|
||||||
rotation_matrix_x.append([0, 0, 0, 1])
|
|
||||||
|
|
||||||
for tri in tris:
|
row0 = Vector4d(math.cos(ui.theta), math.sin(ui.theta), 0, 0)
|
||||||
rotated_z = []
|
row1 = Vector4d(-math.sin(ui.theta), math.cos(ui.theta), 0, 0)
|
||||||
rotated_z.append(matric_mul(tri[0], rotation_matrix_z))
|
row2 = Vector4d(0, 0, 1, 0)
|
||||||
rotated_z.append(matric_mul(tri[1], rotation_matrix_z))
|
row3 = Vector4d(0, 0, 0, 1)
|
||||||
rotated_z.append(matric_mul(tri[2], rotation_matrix_z))
|
|
||||||
|
|
||||||
rotated_x = []
|
rotation_matrix_z = Matrix4x4(row0, row1, row2, row3)
|
||||||
rotated_x.append(matric_mul(rotated_z[0], rotation_matrix_x))
|
|
||||||
rotated_x.append(matric_mul(rotated_z[1], rotation_matrix_x))
|
row0 = Vector4d(1, 0, 0, 0)
|
||||||
rotated_x.append(matric_mul(rotated_z[2], rotation_matrix_x))
|
row1 = Vector4d(0, math.cos(ui.thetax * 0.5), math.sin(ui.thetax * 0.5), 0)
|
||||||
|
row2 = Vector4d(0, -math.sin(ui.thetax * 0.5), math.cos(ui.thetax * 0.5), 0)
|
||||||
|
row3 = Vector4d(0, 0, 0, 1)
|
||||||
|
|
||||||
|
rotation_matrix_x = Matrix4x4(row0, row1, row2, row3)
|
||||||
|
|
||||||
|
for t in tris:
|
||||||
|
row0 = Vector3d(t[0][0], t[0][1], t[0][2])
|
||||||
|
row1 = Vector3d(t[1][0], t[1][1], t[1][2])
|
||||||
|
row2 = Vector3d(t[2][0], t[2][1], t[2][2])
|
||||||
|
|
||||||
|
tri = Matrix3x3(row0, row1, row2)
|
||||||
|
|
||||||
|
row0 = rotation_matrix_z.multiply_3d(tri.row0)
|
||||||
|
row1 = rotation_matrix_z.multiply_3d(tri.row1)
|
||||||
|
row2 = rotation_matrix_z.multiply_3d(tri.row2)
|
||||||
|
|
||||||
|
rotated_z = Matrix3x3(row0, row1, row2)
|
||||||
|
|
||||||
|
row0 = rotation_matrix_x.multiply_3d(rotated_z.row0)
|
||||||
|
row1 = rotation_matrix_x.multiply_3d(rotated_z.row1)
|
||||||
|
row2 = rotation_matrix_x.multiply_3d(rotated_z.row2)
|
||||||
|
|
||||||
|
rotated_x = Matrix3x3(row0, row1, row2)
|
||||||
|
|
||||||
translated = copy.copy(rotated_x)
|
translated = copy.copy(rotated_x)
|
||||||
translated[0][2] = rotated_x[0][2] + 3.0
|
translated.row0.z += 3.0
|
||||||
translated[1][2] = rotated_x[1][2] + 3.0
|
translated.row1.z += 3.0
|
||||||
translated[2][2] = rotated_x[2][2] + 3.0
|
translated.row2.z += 3.0
|
||||||
|
|
||||||
projected = []
|
row0 = projection_matrix.multiply_3d(translated.row0)
|
||||||
projected.append(matric_mul(translated[0], projection_matrix))
|
row1 = projection_matrix.multiply_3d(translated.row1)
|
||||||
projected.append(matric_mul(translated[1], projection_matrix))
|
row2 = projection_matrix.multiply_3d(translated.row2)
|
||||||
projected.append(matric_mul(translated[2], projection_matrix))
|
|
||||||
|
|
||||||
projected[0][0] += 1
|
projected = Matrix3x3(row0, row1, row2)
|
||||||
projected[0][1] += 1
|
|
||||||
projected[1][0] += 1
|
projected.row0.x += 1
|
||||||
projected[1][1] += 1
|
projected.row0.y += 1
|
||||||
projected[2][0] += 1
|
projected.row1.x += 1
|
||||||
projected[2][1] += 1
|
projected.row1.y += 1
|
||||||
projected[0][0] *= .5 * ui.width
|
projected.row2.x += 1
|
||||||
projected[0][1] *= .5 * ui.height
|
projected.row2.y += 1
|
||||||
projected[1][0] *= .5 * ui.width
|
projected.row0.x *= .5 * ui.width
|
||||||
projected[1][1] *= .5 * ui.height
|
projected.row0.y *= .5 * ui.height
|
||||||
projected[2][0] *= .5 * ui.width
|
projected.row1.x *= .5 * ui.width
|
||||||
projected[2][1] *= .5 * ui.height
|
projected.row1.y *= .5 * ui.height
|
||||||
coords = [projected[0][0], projected[0][1], projected[1][0], projected[1][1], projected[2][0], projected[2][1]]
|
projected.row2.x *= .5 * ui.width
|
||||||
|
projected.row2.y *= .5 * ui.height
|
||||||
|
|
||||||
|
coords = [projected.row0.x, projected.row0.y, projected.row1.x, projected.row1.y, projected.row2.x, projected.row2.y]
|
||||||
ui.canvas.create_polygon(coords, fill="", outline="black")
|
ui.canvas.create_polygon(coords, fill="", outline="black")
|
||||||
|
|
||||||
ui.canvas.update()
|
ui.canvas.update()
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import vectors
|
||||||
|
|
||||||
|
class Matrix4x4:
|
||||||
|
def __init__(self):
|
||||||
|
self.row0 = None
|
||||||
|
self.row1 = None
|
||||||
|
self.row2 = None
|
||||||
|
self.row3 = None
|
||||||
|
|
||||||
|
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):
|
||||||
|
raise ValueError("Row must be a Vector4d object.", row1)
|
||||||
|
if not isinstance(row2, vectors.Vector4d):
|
||||||
|
raise ValueError("Row must be a Vector4d object.", row2)
|
||||||
|
if not isinstance(row3, vectors.Vector4d):
|
||||||
|
raise ValueError("Row must be a Vector4d object.", row3)
|
||||||
|
|
||||||
|
self.row0 = row0
|
||||||
|
self.row1 = row1
|
||||||
|
self.row2 = row2
|
||||||
|
self.row3 = row3
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if w != 0:
|
||||||
|
x /= w
|
||||||
|
y /= w
|
||||||
|
z /= w
|
||||||
|
|
||||||
|
return vectors.Vector3d(x, y, z)
|
||||||
|
|
||||||
|
class Matrix3x3:
|
||||||
|
def __init__(self):
|
||||||
|
self.row0 = None
|
||||||
|
self.row1 = None
|
||||||
|
self.row2 = None
|
||||||
|
|
||||||
|
def __init__(self, row0, row1, row2):
|
||||||
|
self.row0 = row0
|
||||||
|
self.row1 = row1
|
||||||
|
self.row2 = row2
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
class Vector4d:
|
||||||
|
def __init__(self, x, y, z, w):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.z = z
|
||||||
|
self.w = w
|
||||||
|
|
||||||
|
class Vector3d:
|
||||||
|
def __init__(self, x, y, z):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
self.z = z
|
||||||
|
|
||||||
|
class Vector2d:
|
||||||
|
def __init__(self, x, y):
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
Reference in New Issue
Block a user