Added more math functionsto the vectors and matrix classes.
This commit is contained in:
@@ -61,7 +61,7 @@ def mouse_start(event):
|
|||||||
ui.canvas.old_coords = event.x, event.y
|
ui.canvas.old_coords = event.x, event.y
|
||||||
|
|
||||||
def mouse_end(event):
|
def mouse_end(event):
|
||||||
x, y = event.x - ui.width / 2, event.y - ui.height / 2#ui.canvas.old_coords[0] - event.x, ui.canvas.old_coords[1] - event.y
|
x, y = event.x - ui.width / 2, event.y - ui.height / 2
|
||||||
if x < 0:
|
if x < 0:
|
||||||
ui.thetax -= .01
|
ui.thetax -= .01
|
||||||
else:
|
else:
|
||||||
@@ -73,11 +73,9 @@ def mouse_end(event):
|
|||||||
ui.thetaz += .01
|
ui.thetaz += .01
|
||||||
|
|
||||||
draw_scene()
|
draw_scene()
|
||||||
#ui.theta += x / ui.width
|
|
||||||
|
|
||||||
def draw_scene():
|
def draw_scene():
|
||||||
ui.canvas.delete("all")
|
ui.canvas.delete("all")
|
||||||
#ui.theta += .01 # scaling factor
|
|
||||||
aspect_ratio = ui.height / ui.width
|
aspect_ratio = ui.height / ui.width
|
||||||
|
|
||||||
projection_matrix = Matrix4x4.get_projection_matrix(fov, aspect_ratio, near_plane, far_plane)
|
projection_matrix = Matrix4x4.get_projection_matrix(fov, aspect_ratio, near_plane, far_plane)
|
||||||
@@ -86,79 +84,56 @@ def draw_scene():
|
|||||||
|
|
||||||
rotation_matrix_x = Matrix4x4.get_x_rotation_matrix(ui.thetax)
|
rotation_matrix_x = Matrix4x4.get_x_rotation_matrix(ui.thetax)
|
||||||
|
|
||||||
#translation = Matrix4x4.get_translation_matrix(Vector3d(0, 0, 16))
|
translation = Matrix4x4.get_translation_matrix(Vector3d(0, 0, 3))
|
||||||
|
|
||||||
#world_matrix = Matrix4x4.get_identity_matrix()
|
world_matrix = Matrix4x4.get_identity_matrix()
|
||||||
#world_matrix = rotation_matrix_z.multiply_matrix(rotation_matrix_x)
|
world_matrix = rotation_matrix_z.multiply_matrix(rotation_matrix_x)
|
||||||
#world_matrix = world_matrix.multiply_matrix(translation)
|
world_matrix = world_matrix.multiply_matrix(translation)
|
||||||
|
|
||||||
|
|
||||||
triangles = []
|
triangles = []
|
||||||
|
|
||||||
for tri in tris:
|
for tri in tris:
|
||||||
# Rotate on the z-axis
|
row1 = world_matrix.multiply_3d(tri[0])
|
||||||
row1 = rotation_matrix_z.multiply_3d(tri.row1)
|
row2 = world_matrix.multiply_3d(tri[1])
|
||||||
row2 = rotation_matrix_z.multiply_3d(tri.row2)
|
row3 = world_matrix.multiply_3d(tri[2])
|
||||||
row3 = rotation_matrix_z.multiply_3d(tri.row3)
|
|
||||||
|
|
||||||
rotated_y = Matrix3x3(row1, row2, row3)
|
transformed = Matrix3x3(row1, row2, row3)
|
||||||
# Rotate on the x-axis
|
|
||||||
row1 = rotation_matrix_x.multiply_3d(rotated_y.row1)
|
|
||||||
row2 = rotation_matrix_x.multiply_3d(rotated_y.row2)
|
|
||||||
row3 = rotation_matrix_x.multiply_3d(rotated_y.row3)
|
|
||||||
|
|
||||||
rotated_x = Matrix3x3(row1, row2, row3)
|
line1 = transformed.row2.subtract_3d(transformed.row1)
|
||||||
# The offset into the screen
|
line2 = transformed.row3.subtract_3d(transformed.row1)
|
||||||
translated = copy.copy(rotated_x)
|
|
||||||
translated.row1.z += 3.0
|
|
||||||
translated.row2.z += 3.0
|
|
||||||
translated.row3.z += 3.0
|
|
||||||
|
|
||||||
# Use cross-product to get the surface normal (a Vector3d)
|
|
||||||
x = translated.row2.x - translated.row1.x
|
|
||||||
y = translated.row2.y - translated.row1.y
|
|
||||||
z = translated.row2.z - translated.row1.z
|
|
||||||
line1 = Vector3d(x, y, z)
|
|
||||||
|
|
||||||
x = translated.row3.x - translated.row1.x
|
|
||||||
y = translated.row3.y - translated.row1.y
|
|
||||||
z = translated.row3.z - translated.row1.z
|
|
||||||
line2 = Vector3d(x, y, z)
|
|
||||||
|
|
||||||
normal = line1.cross_product(line2)
|
normal = line1.cross_product(line2)
|
||||||
|
|
||||||
# Now we normalize the normal
|
normal = normal.get_normalized_form()
|
||||||
length = math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z)
|
|
||||||
normal.x /= length
|
|
||||||
normal.y /= length
|
|
||||||
normal.z /= length
|
|
||||||
|
|
||||||
# Do we display this triangle?
|
# Do we display this triangle?
|
||||||
if normal.dot_product(translated.row1) < 0.0:
|
if normal.dot_product(transformed.row1) < 0.0:
|
||||||
# Lighting
|
# Lighting
|
||||||
light = Vector3d(0, 0, -1) # Shining at the player.
|
light = Vector3d(0, 0, -1) # Shining at the player.
|
||||||
|
|
||||||
length = math.sqrt(light.x * light.x + light.y * light.y + light.z * light.z)
|
light = light.get_normalized_form()
|
||||||
light.x /= length
|
|
||||||
light.y /= length
|
|
||||||
light.z /= length
|
|
||||||
|
|
||||||
dot_product = normal.dot_product(light)
|
dot_product = normal.dot_product(light)
|
||||||
r = abs(int(255 * dot_product))
|
r = abs(int(255 * dot_product))
|
||||||
|
|
||||||
# Scale into view
|
# Scale into view
|
||||||
row1 = projection_matrix.multiply_3d(translated.row1)
|
row1 = projection_matrix.multiply_3d(transformed.row1)
|
||||||
row2 = projection_matrix.multiply_3d(translated.row2)
|
row2 = projection_matrix.multiply_3d(transformed.row2)
|
||||||
row3 = projection_matrix.multiply_3d(translated.row3)
|
row3 = projection_matrix.multiply_3d(transformed.row3)
|
||||||
|
|
||||||
projected = Matrix3x3(row1, row2, row3)
|
projected = Matrix3x3(row1, row2, row3)
|
||||||
|
|
||||||
projected.row1.x += 1
|
projected.row1 = projected.row1.divide_3d(1)
|
||||||
projected.row1.y += 1
|
projected.row2 = projected.row2.divide_3d(1)
|
||||||
projected.row2.x += 1
|
projected.row3 = projected.row3.divide_3d(1)
|
||||||
projected.row2.y += 1
|
|
||||||
projected.row3.x += 1
|
offset = Vector3d(1, 1, 0)
|
||||||
projected.row3.y += 1
|
|
||||||
|
projected.row1 = projected.row1.add_3d(offset)
|
||||||
|
projected.row2 = projected.row2.add_3d(offset)
|
||||||
|
projected.row3 = projected.row3.add_3d(offset)
|
||||||
|
|
||||||
projected.row1.x *= .5 * ui.width
|
projected.row1.x *= .5 * ui.width
|
||||||
projected.row1.y *= .5 * ui.height
|
projected.row1.y *= .5 * ui.height
|
||||||
projected.row2.x *= .5 * ui.width
|
projected.row2.x *= .5 * ui.width
|
||||||
|
|||||||
@@ -10,14 +10,26 @@ class Matrix3x3:
|
|||||||
def row1(self):
|
def row1(self):
|
||||||
return self.rows[0]
|
return self.rows[0]
|
||||||
|
|
||||||
|
@row1.setter
|
||||||
|
def row1(self, value):
|
||||||
|
self.rows[0] = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def row2(self):
|
def row2(self):
|
||||||
return self.rows[1]
|
return self.rows[1]
|
||||||
|
|
||||||
|
@row2.setter
|
||||||
|
def row2(self, value):
|
||||||
|
self.rows[1] = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def row3(self):
|
def row3(self):
|
||||||
return self.rows[2]
|
return self.rows[2]
|
||||||
|
|
||||||
|
@row3.setter
|
||||||
|
def row3(self, value):
|
||||||
|
self.rows[2] = value
|
||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
return self.rows[key]
|
return self.rows[key]
|
||||||
|
|
||||||
@@ -42,6 +54,10 @@ class Matrix4x4(Matrix3x3):
|
|||||||
def row4(self):
|
def row4(self):
|
||||||
return self.rows[3]
|
return self.rows[3]
|
||||||
|
|
||||||
|
@row4.setter
|
||||||
|
def row4(self, value):
|
||||||
|
self.rows[3] = value
|
||||||
|
|
||||||
def multiply_3d(self, vector3d):
|
def multiply_3d(self, vector3d):
|
||||||
x = vector3d.x * self.row1.x + vector3d.y * self.row2.x + vector3d.z * self.row3.x + self.row4.x
|
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
|
y = vector3d.x * self.row1.y + vector3d.y * self.row2.y + vector3d.z * self.row3.y + self.row4.y
|
||||||
|
|||||||
+24
@@ -1,3 +1,5 @@
|
|||||||
|
import math
|
||||||
|
|
||||||
class Vector2d:
|
class Vector2d:
|
||||||
def __init__(self, x, y):
|
def __init__(self, x, y):
|
||||||
self.points = [x, y]
|
self.points = [x, y]
|
||||||
@@ -24,6 +26,9 @@ class Vector2d:
|
|||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
self.points[key] = value
|
self.points[key] = value
|
||||||
|
|
||||||
|
#def get_normalized_form(self):
|
||||||
|
# return Vector3d(self.x / 2, self.y / 2, self.z / 2)
|
||||||
|
|
||||||
class Vector3d(Vector2d):
|
class Vector3d(Vector2d):
|
||||||
def __init__(self, x, y, z):
|
def __init__(self, x, y, z):
|
||||||
self.points = [x, y, z]
|
self.points = [x, y, z]
|
||||||
@@ -43,6 +48,22 @@ class Vector3d(Vector2d):
|
|||||||
# vectors are to one another.
|
# vectors are to one another.
|
||||||
return self.x * vector3d.x + self.y * vector3d.y + self.z * vector3d.z
|
return self.x * vector3d.x + self.y * vector3d.y + self.z * vector3d.z
|
||||||
|
|
||||||
|
def vector_3d_length(self):
|
||||||
|
return math.sqrt(self.dot_product(self))
|
||||||
|
|
||||||
|
def subtract_3d(self, vector3d):
|
||||||
|
return Vector3d(self.x - vector3d.x, self.y - vector3d.y, self.z - vector3d.z)
|
||||||
|
|
||||||
|
def add_3d(self, vector3d):
|
||||||
|
return Vector3d(self.x + vector3d.x, self.y + vector3d.y, self.z + vector3d.z)
|
||||||
|
|
||||||
|
def divide_3d(self, value):
|
||||||
|
return Vector3d(self.x / value, self.y / value, self.z / value)
|
||||||
|
|
||||||
|
def get_normalized_form(self):
|
||||||
|
length = self.vector_3d_length()
|
||||||
|
return Vector3d(self.x / length, self.y / length, self.z / length)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def z(self):
|
def z(self):
|
||||||
return self.points[2]
|
return self.points[2]
|
||||||
@@ -62,3 +83,6 @@ class Vector4d(Vector3d):
|
|||||||
@w.setter
|
@w.setter
|
||||||
def w(self, value):
|
def w(self, value):
|
||||||
self.points[3] = value
|
self.points[3] = value
|
||||||
|
|
||||||
|
#def get_normalized_form(self):
|
||||||
|
# return Vector3d(self.x / 4, self.y / 4, self.z / 4)
|
||||||
|
|||||||
Reference in New Issue
Block a user