## Sunday, September 12, 2010

### Torus knots in Sage with Tachyon and @parallel

After working a bit more on a patch improving the Tachyon raytracer in Sage, I made a movie of a torus knot. The code below was parallelized to use 20 cores at a time on one of the Sage Foundation's lovely Sun Fire X4450s. Frames were animated with ffmpeg. Blogger might degrade the video, so I recommend downloading the original here.

pk = 3qk = 23res = 180trad = .5lab = 'tk_' + str(pk) + '_' + str(qk)def tknot(theta):    return [(2 + trad*cos(qk*theta/pk))*cos(theta), \\(2 + trad*cos(qk*theta/pk))*sin(theta), trad*sin(qk*theta/pk)]@parallel(ncpus = 20)def tknotter(anum):    th = anum*2.0*pi/res    T = Tachyon(xres = 800, yres = 600, camera_center = (4,4,2.5), \\raydepth=12, antialiasing=2)    loc = tknot(th)    nloc = [abs(x)/norm(vector(loc)) for x in loc]    T.texture('s1',color=nloc,specular=1)    T.texture('p1',color=(.5,.5,.5))    T.sphere(loc,.05,'s1')    ci = 0    for sth in srange(0,th,2*pi/res):        e1 = tknot(sth)        e2 = tknot(sth+2*pi/res)        ts = [abs(x)/norm(vector(e1)) for x in e1]        T.texture('t'+str(ci), color=ts)        T.fcylinder(e1, e2, .025,'t'+str(ci))        ci += 1    T.plane((0,0,-4),(0,0,1),'p1')    T.light((6,6,11),.1,(1,1,1))    T.light((5.9,5.9,11),.1,(1,1,1))    T.save(DATA+lab+'%03d.png'%anum)    return 1qin = range(pk*res)s = list(tknotter(qin))for i in range(40):    r2 = os.system('cp '+DATA+lab+'%03d.png '%(pk*res-1) + DATA+lab+'%03d.png'%(pk*res+i))anum = qin[-1] + 41th = anum*2*pi/resT = Tachyon(xres = 800, yres = 600, camera_center = (5,5,3))T.save(DATA+lab+'%03d.png'%anum)

The animation was then done with the following code; if you want to do something similar you would have to use the appropriate path to your ffmpeg executable.
import subprocesssubprocess.call('/home/mhampton/ffmpeg/ffmpeg -qmax 2 -i ' + \\DATA + 'v%3d.png ./t2vest.mp4', shell=True, stdout=file('/dev/null','w'),stderr=file('/dev/null','w'))