Tuesday, August 21, 2007

Final SoC Report

I've written a final SoC report and posted it in the SymPy wiki. Click here to read it. You will also find similar documents from other SymPy SoC participants here.

Saturday, August 18, 2007

VIDEO: Key Bank Tower Implosion (Downtown Salt Lake City, UT)

This is the video I shot of the Key Bank Tower controlled demolition/implosion in downtown Salt Lake City, UT, earlier this morning. We were standing on the East side of the parking lot across the street from the Triad center and the unfortunately re-branded Energy Solutions Arena (formerly the Delta Center). Digg It.

Update: Full HD-res H.264 version.

Thursday, August 9, 2007

SymPy Plotting: Custom Colors Tutorial

One of the most-requested features for SymPy plotting has been the ability to use custom color schemes. I've now implemented this with the syntax described in this post. The upshot is that you can now use any color scheme expressible as a function of x, y, z, u, and/or v. I'll give some concrete examples to get you started, and then you can do something cool with it. We'll start by setting up a plot:

>>> from sympy import symbols, Plot
>>> x,y,z,u,v = symbols('xyzuv')
>>> p = Plot(axes='none')

Now let's plot a saddle and color it by the magnitude of its gradient:

>>> fz = x**2-y**2
>>> Fx, Fy, Fz = fz.diff(x), fz.diff(y), 0
>>> p[1] = fz, 'style=solid'
>>> p[1].color = (Fx**2 + Fy**2 + Fz**2)**(0.5)

Remember that the algorithm for coloring works like this:
  1. Evaluate the color function(s) across the curve or surface.
  2. Find the minimum and maximum value of each component.
  3. Scale each component to the color gradient.
When not specified explicitly, the default color gradient is (r,g,b) = (0.4,0.4,0.4)->(0.9,0.9,0.9). In our case, everything is gray-scale because we have applied the default color gradient uniformly for each color component. When defining a color scheme in this way, you might want to supply a color gradient as well:

>>> p[1].color = (Fx**2 + Fy**2 + Fz**2)**(0.5),
................ (0.1,0.1,0.9), (0.9,0.1,0.1)

Next, let's try a color gradient with four steps:

>>> gradient = [ 0.0, (0.1,0.1,0.9), 0.3, (0.1,0.9,0.1),
................ 0.7, (0.9,0.9,0.1), 1.0, (1.0,0.0,0.0) ]
>>> p[1].color = (Fx**2 + Fy**2 + Fz**2)**(0.5), gradient

The other way to specify a color scheme is to give a separate function for each component r, g, b. With this syntax, the default color scheme is defined:

>>> p[1].color = z,y,x, (0.4,0.4,0.4), (0.9,0.9,0.9)

This maps z->red, y->green, and x->blue. In some cases, you might prefer to use the following alternative syntax:

>>> p[1].color = z,(0.4,0.9), y,(0.4,0.9), x,(0.4,0.9)

You can still use multi-step gradients with three-function color schemes. When somebody uses this to visualize something useful like curvature, I'd really like to hear about it.

Saturday, August 4, 2007

New Plotting Examples

Try running examples/plotting.py in an interactive shell:

Other updates:
  • New experimental option 'use_lambda', which speeds up calculation by an order of magnitude (used in most of the examples, but doesn't work in every case yet).

  • Custom coloring can be applied in real-time:
    >>> p[1].color = 0.3,0.3,0.9 # any solid color
    >>> p[1].color = 'z,y,x' # lambda-based (fast)
    >>> p[1].color = x,y,z # sympy expr of x,y,z
    >>> p[1].color = u,v,u*v, (u,v) # or of parameters

  • Style property:
    >>> p[1].style = 'wireframe'
    >>> p[1].style = 'solid'
    >>> p[1].style = 'both'

  • Natural right-click translation in the plane of the screen.
  • Middle-click drag zoom.
  • Progress percentage displayed in window caption for long calculations.
  • z,c and numpad 1,3 rotate about the z axis regardless of camera angle.
  • x and numpad 5 reset view.

Sunday, July 29, 2007

Mathematicians are a Hungry Bunch

After yesterday's donut, today it's the Ding Dong Surface. Thanks to Alex who originally pointed me to the Kiss Surface (also named after junk food).

>>> p = Plot()
>>> p[1] = sqrt(1-y)*y, [x,0,2*pi,60], [y,-1,4,100], 'mode=cylindrical'

By the way, the torus shown yesterday can be plotted with:

>>> a,b = 1, 0.5
>>> p[2] = (a+b*cos(x))*cos(y), (a+b*cos(x))*sin(y), b*sin(x), [x,0,2*pi,20], [y,0,2*pi,20]

However, at writing there is a hang bug with trig functions in the new SymPy core, so this may or may not work when you try it.

Saturday, July 28, 2007

Just in time for the Simpson's Movie

After weeks of working mostly on the UI, I've spent three or four days reworking the calculation and display code. One result of that effort is support for parametric surfaces (x,y,z) = f(u,v).

Other things:
  • Now using GL display lists for faster rendering.
  • Support for wireframe, solid, and wireframe superimposed on solid rendering modes.
  • Smaller and more readable code base, since all surface and curve modes are now defined in terms of base parametric modes.
  • Preliminary support for custom coloring.
The new code is not hooked up to the Plot interface yet, so that is my goal for today. Hopefully you will see this in SVN by the end of the weekend, possibly tonight.

Tuesday, July 24, 2007

SymPy Plot: First Screenshot of Labeled Axes

Good thing a picture is worth 10**3 words; I'm burnt out. Among other things, it took me way too long to figure out how to automatically position the axis labels after camera rotations. It still isn't perfect. I also need to add in grid lines. I need a break, I've been coding for a nearly unbroken week.