Permalink
Browse files

improved Toroid.py to construct shape lazily

  • Loading branch information...
1 parent 2ea110c commit 6a0486d3798fe41a6fb24fe9234f250aec36e1b2 @jdf committed Sep 8, 2010
Showing with 69 additions and 59 deletions.
  1. +69 −59 examples.py/3D/Form/Toroid/Toroid.py
@@ -1,44 +1,80 @@
"""
* Interactive Toroid
- * PDE by Ira Greenberg, adapted to Python by Jonathan Feinberg
- *
+ * PDE by Ira Greenberg, rewritten in Python by Jonathan Feinberg
+ *
* Illustrates the geometric relationship between Toroid, Sphere, and Helix
* 3D primitives, as well as lathing principal.
- *
- * Instructions:
- * UP arrow key pts++
- * DOWN arrow key pts--
- * LEFT arrow key segments--
- * RIGHT arrow key segments++
- * 'a' key toroid radius--
- * 's' key toroid radius++
- * 'z' key initial polygon radius--
- * 'x' key initial polygon radius++
- * 'w' key toggle wireframe/solid shading
- * 'h' key toggle sphere/helix
+ *
+ * Instructions:
+ * UP arrow key pts++
+ * DOWN arrow key pts--
+ * LEFT arrow key segments--
+ * RIGHT arrow key segments++
+ * 'a' key toroid radius--
+ * 's' key toroid radius++
+ * 'z' key initial polygon radius--
+ * 'x' key initial polygon radius++
+ * 'w' key toggle wireframe/solid shading
+ * 'h' key toggle sphere/helix
"""
-from processing.core import PVector
-
-pts = 40
+pts = 40
radius = 60.0
# lathe segments
segments = 60
-latheAngle = 0
latheRadius = 100.0
-# for shaded or wireframe rendering
+# for shaded or wireframe rendering
isWireFrame = False
# for optional helix
isHelix = False
helixOffset = 5.0
+# The extruded shape as a list of quad strips
+strips = []
+
def setup():
size(640, 360, OPENGL)
+def extrude():
+ dTheta = TWO_PI / pts
+ helicalOffset = 0
+ if isHelix:
+ helicalOffset = - (helixOffset * segments) / 2
+ vertices = [[latheRadius + sin(dTheta * x) * radius,
+ cos(dTheta * x) * radius + helicalOffset]
+ for x in range(pts + 1)]
+ vertices2 = [[0.0, 0.0, 0.0] for x in range(pts + 1)]
+
+ # draw toroid
+ latheAngle = 0
+ dTheta = TWO_PI / segments
+ if isHelix:
+ dTheta *= 2
+ for i in range(segments + 1):
+ verts = []
+ for j in range(pts + 1):
+ v2 = vertices2[j]
+ if i > 0:
+ verts.append(v2[:])
+
+ v2[0] = cos(latheAngle) * vertices[j][0]
+ v2[1] = sin(latheAngle) * vertices[j][0]
+ v2[2] = vertices[j][1]
+ # optional helix offset
+ if isHelix:
+ vertices[j][1] += helixOffset
+
+ verts.append(v2[:])
+ strips.append(verts)
+ latheAngle += dTheta
+
def draw():
+ if not len(strips):
+ extrude()
+
background(50, 64, 42)
# basic lighting setup
lights()
@@ -50,50 +86,20 @@ def draw():
else:
noStroke()
fill(150, 195, 125)
-
+
#center and spin toroid
translate(width / 2, height / 2, -100)
rotateX(frameCount * PI / 150)
rotateY(frameCount * PI / 170)
rotateZ(frameCount * PI / 90)
- # initialize point arrays
- vertices = [PVector() for x in range(pts + 1)]
- vertices2 = [PVector() for x in range(pts + 1)]
- # fill arrays
- angle = 0
- for v in vertices:
- v.x = latheRadius + sin(radians(angle)) * radius
- if isHelix:
- v.z = cos(radians(angle)) * radius - (helixOffset * segments) / 2
- else:
- v.z = cos(radians(angle)) * radius
- angle += 360.0 / pts
-
+
# draw toroid
- latheAngle = 0
- for i in range(segments + 1):
+ for strip in strips:
beginShape(QUAD_STRIP)
- for j in range(pts + 1):
- v2 = vertices2[j]
- if i > 0:
- vertex(v2.x, v2.y, v2.z)
-
- v2.x = cos(radians(latheAngle)) * vertices[j].x
- v2.y = sin(radians(latheAngle)) * vertices[j].x
- v2.z = vertices[j].z
- # optional helix offset
- if isHelix:
- vertices[j].z += helixOffset
-
- vertex(v2.x, v2.y, v2.z)
- # create extra rotation for helix
- if isHelix:
- latheAngle += 720.0 / segments
- else:
- latheAngle += 360.0 / segments
-
+ for v in strip:
+ vertex(v[0], v[1], v[2])
endShape()
-
+
"""
left/right arrow keys control ellipse detail
up/down arrow keys control segment detail.
@@ -104,6 +110,10 @@ def draw():
"""
def keyPressed():
global pts, segments, isHelix, isWireFrame, latheRadius, radius
+
+ # clear the list of strips, to force a re-evaluation
+ del strips[:]
+
if key == CODED:
# pts
if keyCode == UP:
@@ -120,20 +130,20 @@ def keyPressed():
if segments < 80:
segments += 1
# lathe radius
- if key == ord('a'):
+ elif key == ord('a'):
if latheRadius > 0:
latheRadius -= 1
elif key == ord('s'):
latheRadius += 1
# ellipse radius
- if key == ord('z'):
+ elif key == ord('z'):
if radius > 10:
radius -= 1
elif key == ord('x'):
radius += 1
# wireframe
- if key == ord('w'):
+ elif key == ord('w'):
isWireFrame = not isWireFrame
# helix
- if key == ord('h'):
+ elif key == ord('h'):
isHelix = not isHelix

0 comments on commit 6a0486d

Please sign in to comment.