Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions basicShapes.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import numpy as np
import wireframe as wf

def Cuboid((x,y,z), (w,h,d)):

def Cuboid(X, size):
""" Return a wireframe cuboid starting at (x,y,z)
with width, w, height, h, and depth, d. """

x,y,z = X
w,h,d = size
cuboid = wf.Wireframe()
cuboid.addNodes(np.array([[nx,ny,nz] for nx in (x,x+w) for ny in (y,y+h) for nz in (z,z+d)]))
cuboid.addFaces([(0,1,3,2), (7,5,4,6), (4,5,1,0), (2,3,7,6), (0,2,6,4), (5,7,3,1)])

return cuboid

def Spheroid((x,y,z), (rx, ry, rz), resolution=10):
def Spheroid(X, R, resolution=10):
""" Returns a wireframe spheroid centred on (x,y,z)
with a radii of (rx,ry,rz) in the respective axes. """
x,y,z = X
rx, ry, rz = R

spheroid = wf.Wireframe()
latitudes = [n*np.pi/resolution for n in range(1,resolution)]
Expand All @@ -34,9 +39,14 @@ def Spheroid((x,y,z), (rx, ry, rz), resolution=10):

return spheroid

def HorizontalGrid((x,y,z), (dx,dz), (nx,nz)):
def HorizontalGrid(X, D, N):
""" Returns a nx by nz wireframe grid that starts at (x,y,z) with width dx.nx and depth dz.nz. """

x,y,z = X
dx,dz = D
nx,nz = N
print('x', x, 'y', y, 'z', z, 'dx', dx, 'dy', dy, 'nx', nx, 'nz', nz)
asdfsdf
grid = wf.Wireframe()
grid.addNodes([[x+n1*dx, y, z+n2*dz] for n1 in range(nx+1) for n2 in range(nz+1)])
grid.addEdges([(n1*(nz+1)+n2,n1*(nz+1)+n2+1) for n1 in range(nx+1) for n2 in range(nz)])
Expand Down
61 changes: 36 additions & 25 deletions examples.py
Original file line number Diff line number Diff line change
@@ -1,63 +1,69 @@
from __future__ import print_function
import math
import numpy as np
import wireframe as wf
import wireframeDisplay as wd
import basicShapes as shape


def testWireframe():
""" Example of how to create wireframes node by node, and by using the basicShape module.
Creates a triangle and cuboid wireframe and outputs their node, edge and face values. """

# Create a triangle by explictly passing the nodes and edges
print "\nTriangle"
triangle = wf.Wireframe([[100,200,10], [200,200,10], [125,100,500]])
triangle.addEdges([(0,1), (1,2), (2,0)])
print("\nTriangle")
triangle = wf.Wireframe([[100, 200, 10], [200, 200, 10], [125, 100, 500]])
triangle.addEdges([(0, 1), (1, 2), (2, 0)])
triangle.output()

# Create a cuboid using the basicShape module
print "\nCuboid"
print("\nCuboid")
cuboid = shape.Cuboid((100,100,10), (20,30,40))
cuboid.output()


def testTranslate():
""" Example of how to translate a wireframe.
Creates a cuboid and translates it by vector (4,3,1). """

cuboid = shape.Cuboid((100,100,10), (20,30,40))
cuboid.outputNodes()
print "\n> Translate cuboid along vector [4 3 1]"

print("\n> Translate cuboid along vector [4 3 1]")
cuboid.transform(wf.translationMatrix(4, 3, 1))
cuboid.outputNodes()



def testScale():
""" Example of how to scale a wireframe.
Creates a cuboid and scales it by 2, centred on (100,150,200). """

cuboid = shape.Cuboid((100,100,10), (20,30,40))
cuboid.outputNodes()

print "\n> Scale cuboid by 2, centred at (100,150,200)"
print("\n> Scale cuboid by 2, centred at (100,150,200)")
cuboid.transform(wf.scaleMatrix(2, 100, 150, 200))
cuboid.outputNodes()



def testRotate():
""" Example of how to rotate a wireframe.
Creates a cuboid and rotates about its centre by pi/2 radians. """

cuboid = shape.Cuboid((100,100,10), (20,30,40))
cuboid.outputNodes()

# Find rotation matrix
(x,y,z) = cuboid.findCentre()
translation_matrix = wf.translationMatrix(-x, -y, -z)
rotation_matrix = np.dot(translation_matrix, wf.rotateXMatrix(math.pi/2))
rotation_matrix = np.dot(rotation_matrix, -translation_matrix)

print "\n> Rotate cuboid around its centre and the x-axis"
print("\n> Rotate cuboid around its centre and the x-axis")
cuboid.transform(rotation_matrix)
cuboid.outputNodes()


def testWireframeGroup():
""" Example of how to create a group of named wireframes. """

Expand All @@ -66,6 +72,7 @@ def testWireframeGroup():
g.addWireframe('cube2', shape.Cuboid(( 10,200,10), (10,40,20)))
g.output()


def testWireframeDisplay():
""" Create and display a wireframe cube. """

Expand All @@ -74,14 +81,16 @@ def testWireframeDisplay():
viewer.displayFaces = False
viewer.run()


def testSurfaceDisplayWithCube():
""" Create and display a cube with surfaces. """

viewer = wd.WireframeViewer(600, 400)
viewer.addWireframe('cube', shape.Cuboid((225,100,0), (200,200,200)))
viewer.displayEdges = False
viewer.run()



def testSurfaceDisplayWithSphere():
""" Create and display a cube with surfaces. """

Expand All @@ -102,10 +111,11 @@ def testSurfaceDisplayWithSphere():
# colour[1] = 0
# colour[2] = 0

print "Create a sphere with %d faces." % len(viewer.wireframes['sphere'].faces)
print("Create a sphere with %d faces." % len(viewer.wireframes['sphere'].faces))
viewer.displayEdges = False
viewer.run()



def testWireframeDisplay3():
""" Create display with two cuboids, a plane and spheroid. """

Expand All @@ -116,6 +126,7 @@ def testWireframeDisplay3():
viewer.addWireframe('sphere', shape.Spheroid((250,300, 100), (20,30,40)))
viewer.run()


def chooseExample():
examples = ['testWireframe',
'testTranslate',
Expand All @@ -129,18 +140,18 @@ def chooseExample():

makingChoice = True
while makingChoice:
print "\nOptions:"
print("\nOptions:")

for i, e in enumerate(examples, 1):
print " %d. %s" % (i, e)
choice = input("\nChoose an option: ")
print(" %d. %s" % (i, e))
choice = int(input("\nChoose an option: "))

if choice > len(examples)-1:
print '> exit'
print('> exit')
makingChoice = False
else:
print "> %s" % examples[choice-1]
print("> %s" % examples[choice-1])
exec("%s()" % examples[choice-1])

if __name__ == '__main__':
chooseExample()
39 changes: 26 additions & 13 deletions wireframe.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import print_function
import numpy as np


def translationMatrix(dx=0, dy=0, dz=0):
""" Return matrix for translation along vector (dx, dy, dz). """

Expand All @@ -8,12 +10,14 @@ def translationMatrix(dx=0, dy=0, dz=0):
[0,0,1,0],
[dx,dy,dz,1]])


def translateAlongVectorMatrix(vector, distance):
""" Return matrix for translation along a vector for a given distance. """

unit_vector = np.hstack([unitVector(vector) * distance, 1])
return np.array([[1,0,0,0],[0,1,0,0],[0,0,1,0], unit_vector])


def scaleMatrix(s, cx=0, cy=0, cz=0):
""" Return matrix for scaling equally along all axes centred on the point (cx,cy,cz). """

Expand All @@ -22,6 +26,7 @@ def scaleMatrix(s, cx=0, cy=0, cz=0):
[0,0,s,0],
[cx*(1-s), cy*(1-s), cz*(1-s), 1]])


def rotateXMatrix(radians):
""" Return matrix for rotating about the x-axis by 'radians' radians """

Expand All @@ -32,6 +37,7 @@ def rotateXMatrix(radians):
[0,s, c,0],
[0,0, 0,1]])


def rotateYMatrix(radians):
""" Return matrix for rotating about the y-axis by 'radians' radians """

Expand All @@ -42,6 +48,7 @@ def rotateYMatrix(radians):
[-s,0,c,0],
[ 0,0,0,1]])


def rotateZMatrix(radians):
""" Return matrix for rotating about the z-axis by 'radians' radians """

Expand All @@ -52,9 +59,12 @@ def rotateZMatrix(radians):
[0, 0,1,0],
[0, 0,0,1]])

def rotateAboutVector((cx,cy,cz), (x,y,z), radians):

def rotateAboutVector(C, X, radians):
""" Rotate wireframe about given vector by 'radians' radians. """

cx,cy,cz = C
x,y,z = X
# Find angle and matrix needed to rotate vector about the z-axis such that its y-component is 0
rotZ = np.arctan2(y, x)
rotZ_matrix = rotateZMatrix(rotZ)
Expand All @@ -73,7 +83,8 @@ def rotateAboutVector((cx,cy,cz), (x,y,z), radians):

return matrix

class Wireframe:

class Wireframe(object):
""" An array of vectors in R3 and list of edges connecting them. """

def __init__(self, nodes=None):
Expand Down Expand Up @@ -114,19 +125,20 @@ def output(self):
self.outputFaces()

def outputNodes(self):
print "\n --- Nodes --- "
print("\n --- Nodes --- ")
for i, (x, y, z, _) in enumerate(self.nodes):
print " %d: (%d, %d, %d)" % (i, x, y, z)
print(" %d: (%d, %d, %d)" % (i, x, y, z))

def outputEdges(self):
print "\n --- Edges --- "
print("\n --- Edges --- ")
for i, (node1, node2) in enumerate(self.edges):
print " %d: %d -> %d" % (i, node1, node2)
print(" %d: %d -> %d" % (i, node1, node2))

def outputFaces(self):
print "\n --- Faces --- "
print("\n --- Faces --- ")
for i, nodes in enumerate(self.faces):
print " %d: (%s)" % (i, ", ".join(['%d' % n for n in nodes]))
print('nodes', nodes)
print(" %d: (%s)" % (i, ", ".join(['%d' % n for n in nodes[0]])))

def transform(self, transformation_matrix):
""" Apply a transformation defined by a transformation matrix. """
Expand All @@ -147,7 +159,8 @@ def update(self):
""" Override this function to control wireframe behaviour. """
pass

class WireframeGroup:

class WireframeGroup(object):
""" A dictionary of wireframes and methods to manipulate them all together. """

def __init__(self):
Expand All @@ -158,17 +171,17 @@ def addWireframe(self, name, wireframe):

def output(self):
for name, wireframe in self.wireframes.items():
print name
print(name)
wireframe.output()

def outputNodes(self):
for name, wireframe in self.wireframes.items():
print name
print(name)
wireframe.outputNodes()

def outputEdges(self):
for name, wireframe in self.wireframes.items():
print name
print(name)
wireframe.outputEdges()

def findCentre(self):
Expand All @@ -185,4 +198,4 @@ def transform(self, matrix):

def update(self):
for wireframe in self.wireframes.values():
wireframe.update()
wireframe.update()