<div dir="ltr">"""<br>A Visual Python animation showing a "triangular page" going back and<br>forth between triangular book covers laid flat against the XY plane.<br>The page tip traces a semi-circle (not displayed but certainly computed).<br>
As a result of two triangular "flaps" (cover and page) at some dihedral<br>angle, a tetrahedron is defined, actually two, one with each cover as<br>base, tip as opposite vertex. Their volumes will always be the same.<br>
The video pauses in two places (time.sleep()). The Tetrahedron class<br>(imported) is designed to natively return volume in "tetravolumes"<br>but you can flip that switch easily to use xyz_volume instead.<br><br>
Dependencies:<br>Python 3.x (<a href="http://python.org">python.org</a>)<br>Visual Python (<a href="http://vpython.org">vpython.org</a>)<br><br>stickworks.py (3.x version)<br><a href="https://mail.python.org/pipermail/edu-sig/2013-September/010896.html">https://mail.python.org/pipermail/edu-sig/2013-September/010896.html</a><br>
<br>tetravolumes.py<br><a href="https://mail.python.org/pipermail/edu-sig/2013-August/010872.html">https://mail.python.org/pipermail/edu-sig/2013-August/010872.html</a><br>(watch for / repair word-wrapping in this code -- too wide for<br>
mailman defaults)<br><br>Videos and more explanation:<br><a href="http://controlroom.blogspot.com/2013/09/polyhedrons-at-play.html">http://controlroom.blogspot.com/2013/09/polyhedrons-at-play.html</a><br><br>"""<br>
<br>from tetravolumes import Tetrahedron<br>from stickworks import Vector, Edge<br>import math<br>import time<br>from visual import *<br><br><br># This module runs as "__main__" so the visual stuff kicks it off<br>
<br>scene2 = display(title = "Book Covers", width=500, height=500, background=(0,0,0), center=(0,0,0))<br>scene2.forward = (0,1,-.3)<br>scene2.autocenter = False<br>scene2.range = (2,2,4)<br>scene2.select()<br><br>
<br># In this namespace, a rod with its tail at the origin is a Vector while some line<br># segment floating in space with neither end at the origin is an Edge.<br><br># So rods like C0--S1 and even the spine and axis themselves are modeled<br>
# as Edges, not Vectors. Edges are *defined* using two Vectors however,<br># one pointing to each end.<br><br># S0 --- S1 is the spine, two XYZ Vectors (defined in a different module named<br># stickworks. I use the Y axis, with Z considered vertical.<br>
<br>S0 = Vector((0,0.5,0))<br>S1 = -S0<br>spine = Edge(S0, S1) # spine of a book (equilateral triangular book covers)<br><br># C0 -- C1 would be the book cover axis from cover to cover, nailed down and<br># fixed. Again, these are modeled as Vectors. X axis is used.<br>
<br>C0 = Vector((math.sqrt(3)/2,0,0))<br>C1 = -C0<br>axis = Edge(C0, C1) # another fixed Edge<br><br># spine to C0<br>S0C0 = Edge(S0,C0)<br>S1C0 = Edge(S1,C0)<br><br># spine to C1<br>S0C1 = Edge(S0,C1)<br>S1C1 = Edge(S1,C1)<br>
<br>class Page:<br> """<br> triangular page modeled by its tip oscillating<br> between pages.<br> """<br><br> def __init__(self, angle=0):<br> self.angle = angle # degrees<br>
self.tip = self._getVector()<br><br> def delta_angle(self, degrees):<br> self.angle += degrees<br> self.tip = self._getVector()<br><br> def _getVector(self):<br> #The page tip's job is to make an arc using sine and cosine of the dihedral<br>
# angle the page is making with the flap, starting with tip at C0.<br> z = math.sin(math.radians(self.angle)) * axis.length/2<br> x = math.cos(math.radians(self.angle)) * axis.length/2<br> y = 0<br>
return Vector((x,y,z))<br><br>def complementary(page):<br> a = Edge(page.tip, S0).length<br> b = Edge(page.tip, C0).length<br> c = Edge(page.tip, S1).length<br> d = S0C0.length<br> e = S1C0.length<br>
f = spine.length<br> t0 = Tetrahedron(a,b,c,d,e,f)<br><br> a = Edge(page.tip, S0).length<br> b = Edge(page.tip, C1).length<br> c = Edge(page.tip, S1).length<br> d = S0C1.length<br> e = S1C1.length<br>
f = spine.length<br> t1 = Tetrahedron(a,b,c,d,e,f)<br><br> return t0, t1<br><br><br>def inadvertent(page):<br> # stub function marking a 3rd tetrahedron of opposite<br> # edges green and blue, other edges red, as a fall-out,<br>
# like another consequence of the setting for t. Per<br> # Koski's studies.<br> t2 = Tetrahedron( )<br> return t2<br><br><br>spine.draw()<br>S0C0.draw()<br>S1C0.draw()<br>S0C1.draw()<br>S1C1.draw()<br>lamp = local_light(pos=(0,-3,0), color=color.yellow)<br>
page = Page()<br><br>def drawit(page):<br> s=Edge(page.tip, S0, color=(1,0,0))<br> t=Edge(page.tip, C1, color=(0,0,1))<br> u=Edge(page.tip, S1, color=(1,0,0))<br> v=Edge(page.tip, C0, color=(0,1,0))<br> s.draw()<br>
t.draw()<br> u.draw()<br> v.draw()<br> rate(30)<br> return s,t,u,v<br><br>def eraseit(*seq):<br> for obj in seq:<br> obj.erase()<br><br># a loop drives the page back and forth by upping and lowering<br>
# the degrees, of the dihedral angle. So you'll spot where, when I'm<br># close to "regular tetrahedron" (71 degree) I swap in a dihedral angle<br># computed with trig -- you could say it's a still snap shot of the ideal,<br>
# whereas the animation skips such "irrational" dihedrals.<br><br>for i in range(4):<br> for t in range(180):<br> page.delta_angle(1)<br> a,b,c,d = drawit(page)<br> if i == 2 and t == 71:<br>
page = Page(math.degrees(math.asin( 1/sqrt(3))) * 2)<br> T1, T2 = complementary(page)<br> # choose T1.ivm_volume OR T1.xyz_volume<br> tx =text(text="Vol = {:>6.3f}".format(T1.ivm_volume()), pos=(-1, 0, -1),<br>
height=0.4, depth=-0.1, up=(0,0,1), color = color.orange)<br> time.sleep(10)<br> tx.visible = False<br> eraseit(a,b,c,d)<br><br> # The two stops to display volumes are programmed in. It's not like<br>
# I can stop it arbitrarily and have the volume displayed, although the<br> # 2nd video may give that illusion.<br><br> for t in range(180):<br> page.delta_angle(-1)<br> a,b,c,d = drawit(page)<br> if i == 0 and t == 90:<br>
T1, T2 = complementary(page)<br> # choose T1.ivm_volume OR T1.xyz_volume<br> tx =text(text="Vol = {:>6.3f}".format(T1.ivm_volume()), pos=(-1, 0, -1),<br> height=0.4, depth=-0.1, up=(0,0,1), color = color.orange)<br>
time.sleep(10)<br> tx.visible = False<br> eraseit(a,b,c,d)<br><br><br></div>