# Fractal fun & smooth direction change

For your personal fractal collection.

``````from math import pi, sin, cos
from direct.directbase.DirectStart import *
from panda3d.core import *

base.setBackgroundColor(0,0,0)

sm.setPos(0, 0, 0)
sm.setScale(0.2)

boxscale=0.1

for i in range(6):
dummyNode = NodePath("tss"+str(i)) #render.attachNewNode("Dummy Node Name") #NodePath("tss"+str(i)) #
aa=sm.copyTo(dummyNode)
bb=sm.copyTo(dummyNode)
cc=sm.copyTo(dummyNode)

aa.setX(boxscale*2**(i+1))
bb.setX(boxscale*2**(i))
bb.setZ(boxscale*2**(i+1))

sm=dummyNode

sm.reparentTo(render)

direction=1
angleDegrees=0
lasttime=0
difftime=0
direction=1.0
global direction,angleDegrees,lasttime,difftime,direction
angleDegrees += direction*difftime * 50
angleRadians = angleDegrees * (pi / 180.0)
if angleDegrees>25:
if direction>-1:
direction=direction-0.1
if angleDegrees<-25:
if direction<1:
direction=direction+0.1
camera.setPos(25 * sin(angleRadians)+7, -25.0 * cos(angleRadians), 6)
camera.setHpr(angleDegrees, 0, 0)

run() ``````

Fun. But eww, globalsâ€¦

Its a total mystery to me how they sneaked in!

Second try:

``````from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from panda3d.core import *

class FractalScene(ShowBase):
def __init__(self):
ShowBase.__init__(self)
base.setBackgroundColor(0,0,0)

#Seting up the fractal pattern
sm.setPos(0, 0, 0)
sm.setScale(0.1)
boxscale=0.1
for i in range(6):
dummyNode = NodePath("tss"+str(i))
aa=sm.copyTo(dummyNode)
bb=sm.copyTo(dummyNode)
cc=sm.copyTo(dummyNode)
aa.setX(boxscale*2**(i+1))
bb.setX(boxscale*2**(i))
bb.setZ(boxscale*2**(i+1))
sm=dummyNode
sm.reparentTo(render)

#The camera spinning
self.direction=1
self.angleDegrees=0
self.lasttime=0
self.difftime=0
self.direction=1.0

self.angleDegrees += self.direction*self.difftime * 50
angleRadians = self.angleDegrees * (pi / 180.0)
if self.angleDegrees>25:
if self.direction>-1:
self.direction=self.direction-0.05
if self.angleDegrees<-25:
if self.direction<1:
self.direction=self.direction+0.05
camera.setPos(25 * sin(angleRadians)+7, -25.0 * cos(angleRadians), 6)
camera.setHpr(self.angleDegrees, 0, 0)

app = FractalScene()
app.run()``````

Fractal Fun now with partial 3D Snake Game in front.

``````
from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from panda3d.core import *
import random
from direct.gui.OnscreenText import OnscreenText

class FractalScene(ShowBase):
def __init__(self):
ShowBase.__init__(self)
base.setBackgroundColor(0,0,0)
base.disableMouse()
#Seting up the fractal pattern
sm.setPos(0, 0, 0)
sm.setScale(0.1)
boxscale=0.1
for i in range(6):
dummyNode = NodePath("tss"+str(i))
aa=sm.copyTo(dummyNode)
bb=sm.copyTo(dummyNode)
cc=sm.copyTo(dummyNode)
aa.setX(boxscale*2**(i+1))
bb.setX(boxscale*2**(i))
bb.setZ(boxscale*2**(i+1))
sm=dummyNode
self.TheFractal = NodePath("Fractal")
dummyNode.setX(-boxscale*2**6)
sm.reparentTo(self.TheFractal)
self.TheFractal.reparentTo(render)

#The fractal spinning
self.angleDegrees=0
self.lasttime=0
self.difftime=0
self.direction=1.0

self.direction_cam=1
self.angleDegrees_cam=0

##snakecode
base.accept("arrow_left",self.inputhandler,["left"])
base.accept("arrow_up", self.inputhandler,["up"])
base.accept("arrow_down",self.inputhandler,["down"])
base.accept("arrow_right",self.inputhandler,["right"])
base.accept('q',self.inputhandler,["back"])
base.accept('w',self.inputhandler,["front"])
base.accept('h',self.inputhandler,["hideInfoText"])

self.lastpos=Point3(0,0,0)
self.actualkey="up"
self.lastkeyConsumed=True
self.Snakebody=[]
self.Snakelength=8
for i in range(self.Snakelength):
sm.setTransparency(TransparencyAttrib.MAlpha)
sm.clearColor()
#Posiblecolor=[(0,1,0,0.8) ]#,(0,0,1,0.8),(1,0,0,0.8)]
#col=random.choice(Posiblecolor)
sm.setColor(0,1,0,0.8)
sm.reparentTo(render)
sm.setScale(0.9)
self.Snakebody.append(sm)

self.Screensize_X=12
self.Screensize_Y=12
self.runindex=0
self.picuppoint.reparentTo(render)
self.picuppoint.setTransparency(TransparencyAttrib.MAlpha)
self.picuppoint.clearColor()
self.picuppoint.setScale(0.9)
self.picuppoint.setColor(1,0,0,0.5)
self.picuppoint.setPos(random.randint(0,self.Screensize_X-1),0,random.randint(0,self.Screensize_Y-1))

camera.setPos(self.Screensize_X/2.0, -25 , self.Screensize_Y/2.0)
self.TheFractal.setPos(self.Screensize_X/2.0, 10 , 0.0)
self.scoreText = OnscreenText(text = '   0 Points', pos = (0.99, -0.95), scale = 0.1,fg=(1,1,1,1))
self.Infotext = OnscreenText(text = 'Key Info:\n\nUP\t->\tMove Upward\nDOWN\t->\tMove Down\nLEFT\t->\tMove Left\nRIGHT\t->\tMove Right\nq\t->\tMove Front\nw\t->\tMove Back\nh\t->\tHide/Show Key Info', pos = (-0.97, 0.95), scale = 0.05,fg=(1,1,1,1), align=TextNode.ALeft)
self.Points=0

if self.actualkey=="left":
self.lastpos=self.lastpos+Point3(-1,0,0)
elif self.actualkey=="right":
self.lastpos=self.lastpos+Point3(1,0,0)
elif self.actualkey=="down":
self.lastpos=self.lastpos+Point3(0,0,-1)
elif self.actualkey=="up":
self.lastpos=self.lastpos+Point3(0,0,1)
elif self.actualkey=="back":
self.lastpos=self.lastpos+Point3(0,-1,0)
elif self.actualkey=="front":
self.lastpos=self.lastpos+Point3(0,1,0)

for node in self.Snakebody:
if node.getPos()==self.lastpos:
print self.lastpos
textObject = OnscreenText(text = 'Over', pos = (0.0, 0.0), scale = 0.2,fg=(1,1,1,1),bg=(1,0,0,1))

#print self.picuppoint.getPos()
#print self.lastpos
if self.picuppoint.getPos()==self.lastpos:
self.Points=self.Points+1
self.scoreText.setText((4-len(str(self.Points)))*" "+str(self.Points)+" Points")
self.picuppoint.setPos(random.randint(0,self.Screensize_X-1),random.randint(0,5),random.randint(0,self.Screensize_Y-1))

sm.setTransparency(TransparencyAttrib.MAlpha)
sm.clearColor()
sm.setColor(0,1,1,0.5)
sm.reparentTo(render)
sm.setScale(0.9)

self.Snakelength=self.Snakelength+1
self.Snakebody.insert((((self.runindex+1)%self.Snakelength)),sm)

self.runindex=(self.runindex+1)%self.Snakelength
#self.runindex=(self.runindex+1)%self.Snakelength
#sm=self.Snakebody[self.runindex]
#sm.setPos(self.lastpos)
else:
self.runindex=(self.runindex+1)%self.Snakelength
sm=self.Snakebody[self.runindex]
sm.setColor(0,1,0,0.5)

sm.setPos(self.lastpos)

def inputhandler(self,key):
if key=="hideInfoText":
if self.Infotext.isHidden():
self.Infotext.show()
else:
self.Infotext.hide()

if ((key=="right" and self.actualkey!="left") or (key=="left" and self.actualkey!="right") or (key=="down" and self.actualkey!="up") or (key=="up" and self.actualkey!="down") or (key=="back" and self.actualkey!="front") or (key=="front" and self.actualkey!="back")):
self.actualkey=key

self.angleDegrees += self.direction*self.difftime * 50
angleRadians = self.angleDegrees * (pi / 180.0)
if self.angleDegrees>10:
if self.direction>-1:
self.direction=self.direction-0.05
if self.angleDegrees<-10:
if self.direction<1:
self.direction=self.direction+0.05

self.TheFractal.setHpr(self.angleDegrees, 0, 0)

self.angleDegrees_cam += self.direction_cam*self.difftime * 7
angleRadians = self.angleDegrees_cam * (pi / 180.0)
if self.angleDegrees_cam>20:
if self.direction_cam>-1:
self.direction_cam=self.direction_cam-0.1
if self.angleDegrees_cam<-20:
if self.direction_cam<1:
self.direction_cam=self.direction_cam+0.1