Original Post
After playing around with some vector graphics in Pygame/Python, I tried throwing together a simple wireframe box and displaying it in 3D, it works great...until I tried adding movement to it. Trying to translate the box 10 pixels to the left or right causes the box to appear to rotate and stretch. I'm guessing it has to do with the camera space or what have you. I'm just applying a translation Matrix to move the box and a Perspective Matrix to display on screen. EDIT: Cleaned up code [Edited by - Esys on March 23, 2009 7:24:38 PM]
import pygame, math
pygame.init()
def rotateY_Matrix(dir):
rad = math.radians(dir)
return [
(math.cos(rad), 0, math.sin(rad), 0),
(0, 1, 0, 0),
(-math.sin(rad), 0, math.cos(rad), 0),
(0, 0, 0, 1)
]
def origin(faces, center):
origin = []
verts = []
vertList = []
for face in faces:
for side in face:
for i in range(4):
verts.append(side - center)
verts = tuple(verts)
vertList.append(verts)
verts = []
vertList = tuple(vertList)
origin.append(vertList)
vertList = []
print origin
return origin
def retOrigin(faces, center):
origin = []
verts = []
vertList = []
for face in faces:
for side in face:
for i in range(4):
verts.append(side + center)
verts = tuple(verts)
vertList.append(verts)
verts = []
vertList = tuple(vertList)
origin.append(vertList)
vertList = []
print origin
return origin
def perspective_Matrix():
return [
(1,0,0,0),
(0,1,0,0),
(0,0,1,0),
(0,0,.0036,1)
]
def translateX_Matrix(dx):
return [
(1,0,0,dx),
(0,1,0,0),
(0,0,1,0),
(0,0,0,1)
]
def matrixMult(matrix, faces):
n_vect = []
for face in faces:
n_vect.append(
(
(
(matrix[0][0]*face[0][0] + matrix[0][1]*face[0][1] + matrix[0][2]*face[0][2] + matrix[0][3]*face[0][3]),
(matrix[1][0]*face[0][0] + matrix[1][1]*face[0][1] + matrix[1][2]*face[0][2] + matrix[1][3]*face[0][3]),
(matrix[2][0]*face[0][0] + matrix[2][1]*face[0][1] + matrix[2][2]*face[0][2] + matrix[2][3]*face[0][3]),
(matrix[3][0]*face[0][0] + matrix[3][1]*face[0][1] + matrix[3][2]*face[0][2] + matrix[3][3]*face[0][3])
),
(
(matrix[0][0]*face[1][0] + matrix[0][1]*face[1][1] + matrix[0][2]*face[1][2] + matrix[0][3]*face[1][3]),
(matrix[1][0]*face[1][0] + matrix[1][1]*face[1][1] + matrix[1][2]*face[1][2] + matrix[1][3]*face[1][3]),
(matrix[2][0]*face[1][0] + matrix[2][1]*face[1][1] + matrix[2][2]*face[1][2] + matrix[2][3]*face[1][3]),
(matrix[3][0]*face[1][0] + matrix[3][1]*face[1][1] + matrix[3][2]*face[1][2] + matrix[3][3]*face[1][3])
),
(
(matrix[0][0]*face[2][0] + matrix[0][1]*face[2][1] + matrix[0][2]*face[2][2] + matrix[0][3]*face[2][3]),
(matrix[1][0]*face[2][0] + matrix[1][1]*face[2][1] + matrix[1][2]*face[2][2] + matrix[1][3]*face[2][3]),
(matrix[2][0]*face[2][0] + matrix[2][1]*face[2][1] + matrix[2][2]*face[2][2] + matrix[2][3]*face[2][3]),
(matrix[3][0]*face[2][0] + matrix[3][1]*face[2][1] + matrix[3][2]*face[2][2] + matrix[3][3]*face[2][3])
),
(
(matrix[0][0]*face[3][0] + matrix[0][1]*face[3][1] + matrix[0][2]*face[3][2] + matrix[0][3]*face[3][3]),
(matrix[1][0]*face[3][0] + matrix[1][1]*face[3][1] + matrix[1][2]*face[3][2] + matrix[1][3]*face[3][3]),
(matrix[2][0]*face[3][0] + matrix[2][1]*face[3][1] + matrix[2][2]*face[3][2] + matrix[2][3]*face[3][3]),
(matrix[3][0]*face[3][0] + matrix[3][1]*face[3][1] + matrix[3][2]*face[3][2] + matrix[3][3]*face[3][3])
)
)
)
return n_vect
def debugPrint(faces):
face1, face2, face3, face4, face5, face6 = faces
print "face 1: %s" % face1
print "face 2: %s" % face2
print "face 3: %s" % face3
print "face 4: %s" % face4
print "face 5: %s" % face5
print "face 6: %s" % face6
def init():
face1 = [
(100,100,0,1), (150,100,0,1), (150,150,0,1), (100,150,0,1)
]
face2 = [
(100,100,50,1), (150,100,50,1), (150,150,50,1), (100,150,50,1)
]
face3 = [
(100,100,0,1), (100,100,50,1), (150,100,50,1), (150,100,0,1)
]
face4 = [
(100,150,0,1), (100,150,50,1), (150,150,50,1), (150,150,0,1)
]
face5 = [
(100,100,0,1), (100,100,50,1), (100,150,50,1), (100,150,0,1)
]
face6 = [
(100,150,0,1), (150,150,0,1), (150,150,50,1), (100,150,50,1)
]
return (face1,face2,face3,face4,face5,face6)
def displayPoints(points):
#f1, f2, f3, f4, f5, f6 = points
pointList = []
for point in points:
pointList.append(
((point[0][0]/point[0][3], point[0][1]/point[0][3]),
(point[1][0]/point[1][3], point[1][1]/point[1][3]),
(point[2][0]/point[2][3], point[2][1]/point[2][3]),
(point[3][0]/point[3][3], point[3][1]/point[3][3])
))
pointList = tuple(pointList)
return pointList
def drawBox(points, screen):
for point in points:
pygame.draw.lines(screen, (255,0,0), True, point, 1)
def main():
clock = pygame.time.Clock()
running = True
screen = pygame.display.set_mode((640,480))
background = pygame.Surface(screen.get_size())
background.fill((0,0,0))
faces = init()
points = matrixMult(perspective_Matrix(), faces)
points = displayPoints(points)
dir = 0
rotSpeed = 3
tranSpeed = 10
center = (0,0,0,0)
while running:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
print "Right Key"
faces = matrixMult(translateX_Matrix(tranSpeed), faces)
points = matrixMult(perspective_Matrix(), faces)
points = displayPoints(points)
#debugPrint(faces)
elif event.key == pygame.K_LEFT:
print "Left Key"
faces = matrixMult(translateX_Matrix(-tranSpeed), faces)
points = matrixMult(perspective_Matrix(), faces)
points = displayPoints(points)
#debugPrint(faces)
elif event.key == pygame.K_e:
dir += rotSpeed
if dir > 360:
dir = rotSpeed
#faces = origin(faces, center)
faces = matrixMult(rotateY_Matrix(dir), origin(faces, center))
#faces = retOrigin(faces, center)
points = matrixMult(perspective_Matrix(), retOrigin(faces, center))
points = displayPoints(points)
elif event.key == pygame.K_q:
dir -= rotSpeed
if dir < 0:
dir = 360 - rotSpeed
#faces = origin(faces, center)
faces = matrixMult(rotateY_Matrix(dir), origin(faces, center))
#faces = retOrigin(faces, center)
points = matrixMult(perspective_Matrix(), retOrigin(faces, center))
points = displayPoints(points)
screen.blit(background, (0,0))
drawBox(points, screen)
pygame.display.flip()
if __name__ == "__main__": main()