# TowelMap.py: Rossler's Towel Map in interactive 3D.

from visual import *

print """
Right button drag to rotate camera to view scene.
Middle button drag up or down to zoom in or out
"""
scene.title = "Towel Map"
scene.center = vector(0.5,0.0,0.5)
# If you can cross your eyes to see stereo, uncomment the next two lines.
#scene.stereo = 'crosseyed'
#scene.stereodepth = 2
scene.height = 600
scene.width = 600
scene.background = (0,0,0)
scene.forward = (-1.,0.,-1.)
scene.lights = [ vector(-0.25, -0.5, -1.0) ,vector(0.25, 0.5, 1.0) ]

# Rossler's Towel Map, which is pretty close to two coupled
#    Logistic maps, except in three dimensions
def ThreeDMap(a,b,x):
    x[0] = a * x[0] * (1. - x[0]) - .05 * (x[1] + .35) * (1. - 2. * x[2])
    x[1] = .1 * ( (x[1] + .35) * (1. - 2. * x[2]) - 1.) * (1. - 1.9 * x[0])
    x[2] = b * x[2] * (1. - x[2]) + .2 * x[1]
    return x

# Draw box circumscribing state space (unit cube)
curve( pos = [ (0,-.25,0), (1,-.25,0) ], color = (0,0,1))
curve( pos = [ (0,-.25,0), (0,0.25,0) ], color = (0,0,1))
curve( pos = [ (0,-.25,0), (0,-.25,1) ], color = (0,0,1))
curve( pos = [ (1,0.25,1), (0,0.25,1) ], color = (0,0,1))
curve( pos = [ (1,0.25,1), (1,-.25,1) ], color = (0,0,1))
curve( pos = [ (1,0.25,1), (1,0.25,0) ], color = (0,0,1))
curve( pos = [ (0,0.25,1), (0,0.25,0) ], color = (0,0,1))
curve( pos = [ (1,-.25,1), (0,-.25,1) ], color = (0,0,1))
curve( pos = [ (1,0.25,0), (0,0.25,0) ], color = (0,0,1))
curve( pos = [ (1,-.25,0), (1,0.25,0) ], color = (0,0,1))
curve( pos = [ (1,-.25,0), (1,-.25,1) ], color = (0,0,1))
curve( pos = [ (0,0.25,1), (0,-.25,1) ], color = (0,0,1))

# Initial condition
x = vector(.085,-.121,.075)

a = 3.8
b = 3.78
# Iterations to throw away
nTransients = 100
# Iterations to plot
nIterates = 4000

for n in xrange(nTransients):
    x = ThreeDMap(a,b,x)
for n in xrange(nIterates):
    x = ThreeDMap(a,b,x)
    # Draw a sphere at each new point
    sphere(pos=(x[0],3.*x[1],x[2]),color=(1.,0.,0.),radius=0.003)
