# The tachyon object used for rendering plots

When I render a 3d plot using viewer='tachyon', is there any way to "get to" the Tachyon object that is being used, in order to change (or even just examine) it's attributes?

Alternatively, does Tachyon.plot actually work? If so, can I see a sample of working code? I've been able to get Tachyon.parametric_plot to work, but not Tachyon.plot. When I try the examples given in t.plot? they don't work for me -- t.show('verbose='true') says something like:

Parse Error: Encountered a syntax error in file ...

Last question: Is the above question the sort of thing that I should be asking in this forum?

edit retag close merge delete

Sort by » oldest newest most voted

Reading the source for show for 3d plots reveals that you can do the following:

sage: f(x,y) = sin(x*y)
sage: P = plot3d(f, (x,-2,2), (y,-2,2))
sage: opts = P._process_viewing_options({})
sage: T = P._prepare_for_tachyon(opts['frame'],opts['axes'], opts['frame_aspect_ratio'],opts['aspect_ratio'],opts['zoom'])
sage: S = T.tachyon()
sage: type(S)
<type 'str'>


Thus, as you can see, a "Tachyon object" is never created in the course of rendering 3D plots. You just get a string that tells the Tachyon raytracer how to draw the scene. You can then draw the plot with:

sage: tachyon_rt(S)
sage: !open sage.png


I don't think Tachyon.plot works is worth messing with. It should just be deleted. It used to be useful (somewhat) relatively sophisticated code by Josh Kantor and Tom Boothby, but is superseded by what is in the general plot3d code now.

more

OK, now that I understand a little better what's going on, I see why by tachyon plots always look so bad. The tachyon 'resolution' parameter appears to be set to 400 x 400 no matter what 'plot_points' is. So, I can edit the 'scene' string to change that. But is there another way?

( 2010-08-20 20:28:21 +0200 )edit

Hi Mike,

Last things first:

Last question: Is the above question the sort of thing that I should be asking in this forum?

As I understand it, this kind of question is precisely what this site was created for.

Now for the Tachyon questions: I don't know how to get to the Tachyon object directly; it looks like tachyon_repr from parametric surface plots could be on the right track. I believe it returns the string representation of the corresponding Tachyon object. I don't see a function for building a Tachyon object from a string, but it must be easy.

In any case, I'm working on a project where I decided Tachyon is definitely the viewer I want, so I started constructing the Tachyon objects directly (as below). I've used parametric_plot happily, and wasn't aware of problems with plot until you pointed them out. As a workaround until someone gives a better answer, you could simply switch your plots to parametric_plots.

As for plot, I noticed 3 problems:

1. syntax error in your original question: t.show('verbose='true') should be t.show(verbose=True)
2. errors in documentation examples: When pasted to a sage prompt, the following example produces an error because the def line needs to be followed by a blank line:
sage: t = Tachyon(xres=512,yres=512, camera_center=(4,-4,3),viewdir=(-4,4,-3), raydepth=4)
sage: t.light((4.4,-4.4,4.4), 0.2, (1,1,1))
sage: def f(x,y): return float(sin(x*y))
sage: t.texture('t0', ambient=0.1, diffuse=0.9, specular=0.1,  opacity=1.0, color=(1.0,0,0))
sage: t.plot(f,(-4,4),(-4,4),"t0",max_depth=5,initial_depth=3, num_colors=60)  # increase min_depth for better picture
sage: t.show()

3. t.show() doesn't work for me. If you (or others) are having the same problem, I'll open a trac ticket for this. Here are the details of what works and what doesn't:

For me, the following works fine (pink curve on a black background):

sage: f = lambda t: (t,t^2,t^3)
sage: t = Tachyon(camera_center=(5,0,4))
sage: t.texture('t')
sage: t.light((-20,-20,40), 0.2, (1,1,1))
sage: t.parametric_plot(f,-5,5,'t',min_depth=6)
sage: t.show(verbose=True)


On the other hand, the following seems to be broken (but not because of def--note that I've changed that to a lambda function); my guess is that the data file Tachyon is attempting to show is not formatted quite right:

sage: t = Tachyon(xres=512,yres=512, camera_center=(4,-4,3),viewdir=(-4,4,-3), raydepth=4)
sage: t.light((4.4,-4.4,4.4), 0.2, (1,1,1))
sage: f = lambda x,y : float(sin(x*y))
sage: t.texture('t0', ambient=0.1, diffuse=0.9, specular=0.1,  opacity=1.0, color=(1.0,0,0))
sage: t ...
more

ha! William's answer came while I was writing my overly long answer :)

( 2010-08-19 14:32:45 +0200 )edit

Thanks. I can't rate answers, since I don't have points. But that was very helpful. -Mike

( 2010-08-19 16:23:40 +0200 )edit

Thanks :) I'm having trouble editing this answer, but if I could I would note that William's answer gives what I think is the way to render strings with Tachyon: tachyon_rt . . . I've spent a fair amount of time reading the 3d plot documentation, and I haven't noticed this function before.

( 2010-08-20 00:07:27 +0200 )edit

Yes, I believe you're right. I read the second answer first :-)

( 2010-08-20 17:21:33 +0200 )edit

William Stein's answer was very helpful for me, but I also wanted to animate output of a plot3d based function (specifically I was trying to animate a surface of revolution, therefore I was using the revolution_plot3d function, but it's the same idea). Essentially, if you look at how the tachyon string is created, you can recreate the functionality quite simply. Here's a function that allows you to combine a plot3d output with a Tachyon object.

from sage.plot.plot3d.base import flatten_list
from sage.plot.plot3d.transform import Transformation

def combineTachyonPlot(T,P):
P = P.transform(scale=[-1,1,1]) # Tachyon does not have a right-hand-rule coordinate system
render_params = P.default_render_params()
return r"""
begin_scene
%s
%s
%s
%s
%s
end_scene"""%(
T._res(),
T._camera(),
'\n'.join([x.str() for x in T._objects]),
'\n'.join(sorted([t.tachyon_str() for t in P.texture_set()])),
'\n'.join(flatten_list(P.tachyon_repr(render_params))))

# Example how to use this

T = Tachyon(xres=1024,yres=576, camera_center=(0,20,20), updir=(0,0,1) , viewdir=(0,-20,-20), antialiasing=True)
T.light((4,3,5), 0.2, (1,1,1))
T.texture('bg', ambient=1, diffuse=1, specular=1, opacity=1, color=(1,1,1))
T.plane((-2000,-1000,-500),(2.3,2.4,2.0),'bg')

u,v = var('u,v')
P = plot3d(u^2+v^2,(-2,2),(-2,2))

tachyon_rt(combineTachyonPlot(T,P))


You can add things to the Tachyon object as you see fit, lights, backgrounds, spheres, etc. You can also add a 2-dimensional plot to the variable P and Tachyon will render it as well.

more

I've wanted to have something like this for a long time -- thanks for posting the code. I wrote something similar a while ago, but never cleaned it up enough to post it.

( 2014-02-20 10:16:23 +0200 )edit

It would be *great* if this functionality were added to Sage, so that one can add a Tachyon object and a Graphics3d object to get either a Tachyon object or (maybe better) some subclass of Tachyon. I've opened a ticket for this at http://trac.sagemath.org/ticket/15837 Would you like to take a stab at this @process91 ?

( 2014-02-20 10:16:42 +0200 )edit

@niles I would love to take a stab at it; I think the best way to go about it would be to add a method to Tachyon objects which allows you to attach plot3d elements to the Tachyon object similarly to how you can add a sphere. I will check out the trac ticket and see if I can implement this soon. After this is completed, animating 3d graphs similarly to how 2d graphs are animated should be quite simple (this is actually why I created the above function). The only thing that will need to be changed is the way of thinking about animating - we really don't want to animate plot3d for instance, we want to animate a Tachyon object with a plot3d object attached to it. We can, of course, hide this in the animation code.

( 2014-02-20 20:47:17 +0200 )edit

There is something "odd" about how the site is handling this question. It shows "NO" answers, even though it has two. Also, the two tags "tachyon" and "plot3d" don't show up in the list of tags on the site. I think, maybe, this happened because I accidentally posted the question twice, and so one of duplicate posts had to be deleted? In any event, I just wanted to note it. Hopefully it is only this one question, and not a generic problem.

more

And, interestingly, when I posted that last answer, I got the error: Question' object has no attribute 'tag_selections'

( 2010-08-22 14:04:54 +0200 )edit