How to write a python expression for IPO driver that follows sine curve?

Using the pydriver single line expression in the IPO curve editor, i want to make my objects location follow a sine curve. How do i do this. What is the line of code i need to type and what is the variable for controlling hte Time axis.

math.sin(Blender.Get(“curframe”))

does that help?

http://wiki.blender.org/index.php/BlenderDev/PyDrivers

If you want to control not only one channel per time but instead the whole transformation, you can also create a pyConstraint. There is a template file in the scripts directory to get you started.

Does this help?

math: math.sin(Blender.Get(“curframe”))

from http://wiki.blender.org/index.php/BlenderDev/PyDrivers

If you want to control the entire transformation instead of just one channel per time, you can also create a pyConstraint. There is a template file in the script directory of blender “scripttemplate_pyconstraint.py”

i’d like to know this one as well

I put together an entire event processor that will move objects to different locations over time, generate events when they arrive and keep track of everything inside the python dictionary.

You can find the post here:
http://blenderartists.org/forum/showthread.php?t=121608

I have uploaded the BLEND file in another fourm. For some reason you can not attach BLEND files in the Python forum. This is unfortunate because it leads to cross posting in order to demonstrate a concept.
http://blenderartists.org/forum/showthread.php?p=1217482#post1217482

Here is the code, paste it in to the framechange event of the camera or the cube:


import Blender as B
import math
from Blender import Scene
from Blender import Mathutils as Math
from math import cos, sin, pi, exp, radians
# Fetch our storage dictionary from the registry.
#The registry is used as a storage mechanism. 
#Blender loses all variable information when the frame changes.
#So values are fetched and stored in the dictionary.
def setRegistryItem (passedKey, ang):
global myDict
try:
#You can add more values in here.
myDict[(passedKey + 'angle')] = ang
except:
return
 
def getRegistryItem (passedKey):
global myDict
try:
ang = float(myDict[(passedKey + 'angle')])
return ang
except:
return 0
tempRadius = 20.0
RegistryKey = 'MyCubeAngle'
#print RegistryKey
myDict= B.Registry.GetKey(RegistryKey)
if not myDict: 
# Our dictionary does NOT exist, let's create one.
myDict = {}
setRegistryItem (RegistryKey,0) #Default our angle to 0 on first run.
 
#Fetch the source values from the registry.
tempAngle = getRegistryItem (RegistryKey)
localScene= Scene.GetCurrent()
ob = B.Object.Get("Cube")
frame = B.Get('curframe')
if frame == 1:
#Reset our values on rewind.
ob.setLocation (0,0,0)
tempAngle = -1
else:
x = frame/10 #the frame number is the x position.
y = tempRadius * math.sin(math.radians(tempAngle))
ob.setLocation (x, y, 0)
tempAngle = tempAngle + 3
setRegistryItem (RegistryKey,tempAngle) 
# Return our dictionary back to the registry.
B.Registry.SetKey(RegistryKey, myDict)
# No need to update the scene, that is done after this frameChange event is processed by the system.

You will have to play with the parameters and adjust it as needed.
The system does reset to zero on rewind so if the cube gets lost simply rewind and it should reappear at the origin.

Also:

math: math.sin(Blender.Get(“curframe”))

from http://wiki.blender.org/index.php/BlenderDev/PyDrivers

If you want to control the entire transformation instead of just one channel per time, you can also create a pyConstraint. There is a template file in the script directory of blender “scripttemplate_pyconstraint.py”

theres another way to get python to work in a single line expression when i press “n-key” in the ipo curve editor. I need a single line expressio that gives me a sine curve based on time axis. How do i do this?

You could try to set


m.sin(Blender.Scene.GetCurrent().getRenderingContext().currentFrame()/10.0)

as Python expression of some axis (try x for instance). This will make the object move along x axis. The idea is that we derive the driving value from current frame in this case. It’s fine to use any other driver (ie. some property of another object) for instance.

“/10.0” is used just to scale the frame value down a bit. If you look at the way the sine behaves, you will understand this better.

To get the object move “forward” along y axis while moving along x, try adding just


Blender.Scene.GetCurrent().getRenderingContext().currentFrame()/10.0

as a driver for the y axis.

Note that drivers won’t work if you have manually keyed them so be sure to get rid of any IPOs they might already have.

If you want to tidy things up, look into http://wiki.blender.org/index.php/BlenderDev/PyDrivers . It would probably make sense to put the part that gets the current frame into a function of it’s own.

I am not sure what you mean by “time axis” but hopefully you will be able to adapt it to the drivers above.

@Mr Awsome
drive your LocY channel with the expression: sin(b.Get(‘curtime’))
and your LocX channel with: b.Get(‘curtime’)
You might need scaling it of course, but this is the basic idea.
On http://wiki.blender.org/index.php/BlenderDev/PyDrivers you can find which modules are available inside these onliner IPO drivers and on http://www.blender.org/documentation/247PythonDoc/Blender-module.html#Get which other usefull variables (like current frame number and such).

Varken,
So you would be using the frame number as the radian input to the SIN function?

@atom:
yep, sort of: b.Get(‘curtime’) should give you the elapsed time (= framenumber * framerate) while b.Get(‘curframe’) should give you the framenumber. Each would do, because you can scale it by some sensible constant. (the framerate is set in de Format tab in the Renderbuttons).
For example, say you want to move our blender object 3 blender units per second along the x-axis and perform a sinus-like motion along the y-axis every 2 seconds from -2 blender units to 2 b.u. you would set up to drivers like this:
locx: 3.0b.Get(‘curtime’)
locy: 2.0
sin(2pib.Get(‘curtime’)/2.0)

Can anyone give the exact expression to type in. I can’t seem to get it to work. It doesnt say theres an error in expression but the IPO curve seems unaffected. What is the exact expression for a sine curve that i must put into the driver through n-key (Transform Properties)?

@mr awesome: the expressions in my post #6 are exactly what i typed in (blender 2.47 official build, full python 2.5.2 install, although i don’t think the latter will matter in this case)

Channels driven only by Python expressions won’t display an IPO curve. AFAIK, if you have an IPO curve already in place for a channel, the driver expression won’t work because the IPO curve overrides the expression.