Scipy 2008 Sage Tutorial
system:sage

<center><font color="darkblue"><h1>Scipy 2008 Sage Tutorial</h1></font></center>

<center><font color="darkblue"><h2>Tuesday, August 19, 2008</h2></font></center>

<center><font color="darkblue"><h3>William Stein</h3></font></center>

<font size=+2>
<table bgcolor="#eaeaea" align=center cellpadding=20 width=50% border=1><tr><td>
<ol>
<li> Using Sage
<li> Drawing 3d Plots
</ol>
</td></tr></table>
</font>

<br><br>

<br><br>
<hr>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>




<center><h1>Sage?</h1></center>
<font size=+1>
<table bgcolor="#eaeaea" align=center cellpadding=20 width=75% border=1><tr><td>
The goal of the Sage project is to <i>create a viable Python-based 
open source free <font color='darkred'>alternative to Magma, Maple, Mathematica, and Matlab</font>.</i>
<br><br>
<b>Definition (Sage).</b> <i>Sage</i> is
<ol>
<li> a <b>Python-based distribution</b> of free open source mathematics software, including the scipy/numpy/matplotlib stack. 
<li> a <b>large new Python math library</b> that fills in gaps and implements new algorithms
(about 300K lines, about 1/3 of which is Cython). 
<li> uniform <b>interfaces</b> to Magma, Maple, Mathematica, Matlab, and other math software.
</ol>
</td></tr></table>
</font>


<br><br>
<hr>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>




<center><font color='black' size=+1><h1>User Interface</h1></font></center>


<font size=+1>
<table bgcolor="#eaeaea" align=center cellpadding=20 width=50% border=1><tr><td>
<ol>
<li> Command Line 
<li> The Sage Preparser
<li> The Sage Notebook
<li> Interact
</ol>
</td></tr></table>
</font>


<font color="black"><h1>1. The Command Line</h1></font>
Try out the Sage command line by typing "./sage" in SAGE_ROOT.  The Sage command
prompt is a simply a customized version of IPython:
<center>
<table border=1 cellpadding=10><tr><td><font size=+1  color="#333">
<pre>
teragon-2:~ was> sage
----------------------------------------------------------------------
| SAGE Version 3.1.1, Release Date: 2008-08-16                       |
| Type notebook() for the GUI, and license() for information.        |
----------------------------------------------------------------------

sage: 2 + 3
5
sage: plot(sin(x^2), 0,3)
[a static matplotlib-rendered plot appears]
sage: quit
Exiting SAGE (CPU time 0m0.63s, Wall time 2m36.47s).
Exiting spawned Maxima process.
</pre></font></center></td></tr></table>

{{{id=95|

///
}}}

{{{id=10|

///
}}}

{{{id=9|

///
}}}

<font color="black"><h1>2. The Sage Preparser</h1></font>

By default all input to Sage is preparsed just a bit.  This makes Sage much more comfortable
to use for many students and mathematicians.  I can be confusing and troublesome for Python users
and people doing a lot of numerical computations.

{{{id=15|
5/3
///
5/3
}}}

{{{id=8|
%python
# Putting %python at the top of a cell turns off the preparser 
# for that cell, thus making it a "pure Python" cell.
# You can also change the 
5/3
///
1
}}}

{{{id=1|
# The preparse command shows you precisely what the preparser
# does to your input:

preparse('5/3')
///
'Integer(5)/Integer(3)'
}}}

{{{id=18|
print preparse('3.594990283409283409823094829038409283490823094820384')
# NOT a float
3.594990283409283409823094829038409283490823094820384
///
RealNumber('3.594990283409283409823094829038409283490823094820384')
3.594990283409283409823094829038409283490823094820384
}}}

{{{id=19|
import numpy
numpy.array([2.3, 4.5])
///
array([2.30000000000000, 4.50000000000000], dtype=object)
}}}

{{{id=20|
import numpy
numpy.array([2.3, 4.5], dtype=float)
///
array([ 2.3,  4.5])
}}}

{{{id=21|
Integer = int; RealNumber = float
print numpy.array([2.3, 4.5])
print numpy.array([1,2,3])
///
[ 2.3  4.5]
[1 2 3]
}}}

{{{id=24|
# Fix them back
reset("Integer RealNumber")
///
}}}

{{{id=26|
# Another nice preparser convenience (follows mostly an old PEP):
[1..5]
///
[1, 2, 3, 4, 5]
}}}

{{{id=27|
preparse('[1..5]')
///
'(ellipsis_range(Integer(1),Ellipsis,Integer(5)))'
}}}

{{{id=23|
(1..5)
///
<generator object at 0x84c12b0>
}}}

{{{id=17|
[4.5,4.7,..,6]
///
[4.50000000000000, 4.70000000000000, 4.90000000000000, 5.10000000000000, 5.30000000000000, 5.50000000000000, 5.70000000000000, 5.90000000000000]
}}}

{{{id=29|

///
}}}

{{{id=28|

///
}}}

{{{id=16|

///
}}}

{{{id=4|

///
}}}

<font color="black"><h1>3. The Sage Notebook</h1></font>
You are using the Sage notebook right now.  It provides a web-based interface
to Sage.   It is "an AJAX application" (like Gmail):
<ol>
<li> A <b>webserver</b> written from scratch in Python using <b>Twisted Web2</b>.
<li> A <b>Javascript client</b> written from scratch that is about 3500 lines of code.
It uses jquery a tiny bit. 
</ol>

There is another similar stand-alone project called <a href="http://knoboo.com/">Knoboo</a> 
that was started by the student who also co-authored the first version of the Sage notebook.
Once their project is stable, I intend to incorporate their best ideas and code back into 
the Sage notebook.  

<br><br>
There is an overview of most of the features of the Sage notebook in the help screen.

<center>
<font size=+2><b>Click the Help Link in the Upper Right</b></font>
</center>

<br><br>
<b>Show off some cool tricks:</b>
<ol>
<li> How to get interactive help (Type "obj.[tab key]" and "obj.foo([tab key]").  Get source with "obj.foo??[tab key]".
<li> Evaluate cells using shift-enter. 
<li> That output appears as it is computed (for loop with sleep).
<li> Large output is saved to a file (digits of pi).
<li> Toggle word wrap of output
<li> Delete all output.
<li> Interrupting and Restarting the worksheet "kernel" process. 
<li> Indenting blocks of code (tab and shift-tab).
<li> Breaking and joining cells (control-; and control-backspace).
<li> Inserting new cell after current one (alt-enter).
</ol>

{{{id=25|
for n in range(6):
    sleep(1)
    print n
///
0
1
2
3
4
5
}}}

{{{id=30|
# Compute a hundred thousand decimal digits of pi and display them.
# Output eventually appears in a linked file.
time s = str(N(pi,digits=10^5))
print s
///
}}}

{{{id=31|
# Much better:
time open("digits.txt",'w').write(str(N(pi, digits=10^6)))
///
Time: CPU 1.31 s, Wall: 1.34 s
}}}

{{{id=32|

///
}}}

{{{id=33|

///
}}}

{{{id=34|

///
}}}

<br><br>
<b>Your Own Sage Server</b>
You can run your own Sage notebook server, preferably from a virtual machine
using a separate account for worksheets, for security purposes.  
Type notebook? for more details. 
<ol>
<li> I often run special-purpose notebooks on servers for myself or small groups of people.
These must be secure (https).<br><br>
<li> I run completely public notebook servers at sagenb.org and 
<tt>https://sage.math.washington.edu:8102</tt> and 
<tt>https://sage.math.washington.edu:8103</tt>.  These are more locked down.<br><br>
<li> Nobody yet embeds sage in other web pages via some sort of cgi-bin
or javascript protocol... yet!.  But actually the code already exists
to basically do something like this; Robert Bradshaw did write a simple server 
that should make this pretty easy. It's just not got used yet.
</ol>

{{{id=56|

///
}}}

{{{id=65|

///
}}}

{{{id=75|

///
}}}

<br><br><br><br>


<font color="black"><h1>4. Interact</h1></font>
Interact is an incredibly useful feature of the Sage notebook.  It is inspired by:
<ol>
<li> Enthought's traits
<li> Mathematica's Manipulate command. 
</ol>

It is less powerful than both of the above, but is extremely simple to use and
does prove much more useful than nothing :-).  
<br><br>
Note: Development of interact is partly funded by the Google Summer of Code (Igor Tolkov). 
<br><br>

The easiest way to use interact is to just put the <tt>@interact</tt> decorator
right before a function definition.  Sage generates a widget to control each of
the input variables.   Some defaults have a special value, e.g., (a,b) means "slider
from a to b" and [a,b,c] means "three buttons labeled a,b, and c". 
Try it out!

<ol>
<li> Put @interact in front of some simple functions and watch them go.
<li> interact? gives list of all controls and how default arguments are parsed.
<li> <a target="_new" href="http://wiki.sagemath.org/interact">http://wiki.sagemath.org/interact</a> has about
100 interesting nontrivial examples of interact.
</ol>

{{{id=12|
@interact  # put this right before your function
def print_pi(n=(10..10000)):
    # stuff displayed here gets put in the output
    print N(pi, digits=n)
///
<html><div padding=6 id='div-interact-12'> <table width=800px height=400px bgcolor='#c5c5c5'
                 cellpadding=15><tr><td bgcolor='#f9f9f9' valign=top align=left><table><tr><td align=right><font color="black">n </font></td><td><table><tr><td>
    	<div id='slider-n-12' class='ui-slider-3' style='padding:0px;margin:0px;'><span class='ui-slider-handle'></span></div>
    	</td><td><font color='black' id='slider-n-12-lbl'></font></td></tr></table><script>(function(){ var values = ["10","30","50","70","90","110","130","150","170","190","210","230","250","270","290","310","330","350","370","390","410","430","450","470","490","510","530","550","570","590","610","630","650","670","690","710","730","750","770","790","810","830","850","870","890","910","930","950","970","990","1011","1031","1051","1071","1091","1111","1131","1151","1171","1191","1211","1231","1251","1271","1291","1311","1331","1351","1371","1391","1411","1431","1451","1471","1491","1511","1531","1551","1571","1591","1611","1631","1651","1671","1691","1711","1731","1751","1771","1791","1811","1831","1851","1871","1891","1911","1931","1951","1971","1991","2012","2032","2052","2072","2092","2112","2132","2152","2172","2192","2212","2232","2252","2272","2292","2312","2332","2352","2372","2392","2412","2432","2452","2472","2492","2512","2532","2552","2572","2592","2612","2632","2652","2672","2692","2712","2732","2752","2772","2792","2812","2832","2852","2872","2892","2912","2932","2952","2972","2992","3013","3033","3053","3073","3093","3113","3133","3153","3173","3193","3213","3233","3253","3273","3293","3313","3333","3353","3373","3393","3413","3433","3453","3473","3493","3513","3533","3553","3573","3593","3613","3633","3653","3673","3693","3713","3733","3753","3773","3793","3813","3833","3853","3873","3893","3913","3933","3953","3973","3993","4014","4034","4054","4074","4094","4114","4134","4154","4174","4194","4214","4234","4254","4274","4294","4314","4334","4354","4374","4394","4414","4434","4454","4474","4494","4514","4534","4554","4574","4594","4614","4634","4654","4674","4694","4714","4734","4754","4774","4794","4814","4834","4854","4874","4894","4914","4934","4954","4974","4994","5015","5035","5055","5075","5095","5115","5135","5155","5175","5195","5215","5235","5255","5275","5295","5315","5335","5355","5375","5395","5415","5435","5455","5475","5495","5515","5535","5555","5575","5595","5615","5635","5655","5675","5695","5715","5735","5755","5775","5795","5815","5835","5855","5875","5895","5915","5935","5955","5975","5995","6016","6036","6056","6076","6096","6116","6136","6156","6176","6196","6216","6236","6256","6276","6296","6316","6336","6356","6376","6396","6416","6436","6456","6476","6496","6516","6536","6556","6576","6596","6616","6636","6656","6676","6696","6716","6736","6756","6776","6796","6816","6836","6856","6876","6896","6916","6936","6956","6976","6996","7017","7037","7057","7077","7097","7117","7137","7157","7177","7197","7217","7237","7257","7277","7297","7317","7337","7357","7377","7397","7417","7437","7457","7477","7497","7517","7537","7557","7577","7597","7617","7637","7657","7677","7697","7717","7737","7757","7777","7797","7817","7837","7857","7877","7897","7917","7937","7957","7977","7997","8018","8038","8058","8078","8098","8118","8138","8158","8178","8198","8218","8238","8258","8278","8298","8318","8338","8358","8378","8398","8418","8438","8458","8478","8498","8518","8538","8558","8578","8598","8618","8638","8658","8678","8698","8718","8738","8758","8778","8798","8818","8838","8858","8878","8898","8918","8938","8958","8978","8998","9019","9039","9059","9079","9099","9119","9139","9159","9179","9199","9219","9239","9259","9279","9299","9319","9339","9359","9379","9399","9419","9439","9459","9479","9499","9519","9539","9559","9579","9599","9619","9639","9659","9679","9699","9719","9739","9759","9779","9799","9819","9839","9859","9879","9899","9919","9939","9959","9979","10000"]; setTimeout(function() {
    $('#slider-n-12').slider({
    	stepping: 1, minValue: 0, maxValue: 499, startValue: 0,
    	change: function () { var position = Math.ceil($('#slider-n-12').slider('value')); if(values!=null) $('#slider-n-12-lbl').text(values[position]); interact(12, "sage.server.notebook.interact.update(12, \"n\", 64, sage.server.notebook.interact.standard_b64decode(\""+encode64(position)+"\"), globals())"); },
    	slide: function() { if(values!=null) $('#slider-n-12-lbl').text(values[Math.ceil($('#slider-n-12').slider('value'))]); }
    });
    if(values != null) $('#slider-n-12-lbl').text(values[Math.ceil($('#slider-n-12').slider('value'))]);
    }, 1); })();</script></td></tr>
</table><div id='cell-interact-12'><?__SAGE__START>
        <table border=0 bgcolor='#white' width=100% height=100%>
        <tr><td bgcolor=white align=left valign=top><pre><?__SAGE__TEXT></pre></td></tr>
        <tr><td  align=left valign=top><?__SAGE__HTML></td></tr>
        </table><?__SAGE__END></div></td>
                 </tr></table></div>
                 </html>
}}}

{{{id=13|
# You can still use the function as normal.
print_pi(100)
///
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
}}}

{{{id=14|
@interact
def _(f = sin(x*cos(x)), order=[1..5], x0=(1,(-1,5))):
    p   = plot(f,-1,5, thickness=2)
    dot = point((x0,f(x0)),pointsize=80,rgbcolor=(1,0,0))
    ft = f.taylor(x,x0,order)
    pt = plot(ft,-1, 5, color='green', thickness=2)
    html('$f(x)\;=\;%s$'%latex(f))
    html('$\hat{f}(x;%s)\;=\;%s+\mathcal{O}(x^{%s})$'%(x0,latex(ft),order+1))
    show(p + pt + dot, ymin=p.ymin(), ymax=p.ymax())
///

<html><div padding=6 id='div-interact-14'> <table width=800px height=400px bgcolor='#c5c5c5'
                 cellpadding=15><tr><td bgcolor='#f9f9f9' valign=top align=left><table><tr><td align=right><font color="black">f&nbsp;</font></td><td><input type='text' value='sin(x*cos(x))' size=80 onchange='interact(14, "sage.server.notebook.interact.update(14, \"f\", 1, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'></input></td></tr>
<tr><td align=right><font color="black">order&nbsp;</font></td><td><table style="border:1px solid #dfdfdf;background-color:#efefef">
<tr><td><button style='border-style:inset;' value='0' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(14, "sage.server.notebook.interact.update(14, \"order\", 2, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>1</button>
<button style='border-style:outset;' value='1' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(14, "sage.server.notebook.interact.update(14, \"order\", 2, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>2</button>
<button style='border-style:outset;' value='2' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(14, "sage.server.notebook.interact.update(14, \"order\", 2, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>3</button>
<button style='border-style:outset;' value='3' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(14, "sage.server.notebook.interact.update(14, \"order\", 2, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>4</button>
<button style='border-style:outset;' value='4' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(14, "sage.server.notebook.interact.update(14, \"order\", 2, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>5</button>
</td></tr></table></td></tr>
<tr><td align=right><font color="black">x0&nbsp;</font></td><td><table><tr><td>
    	<div id='slider-x0-14' class='ui-slider-3' style='padding:0px;margin:0px;'><span class='ui-slider-handle'></span></div>
    	</td><td><font color='black' id='slider-x0-14-lbl'></font></td></tr></table><script>(function(){ var values = ["-1.0","-0.987975951904","-0.975951903808","-0.963927855711","-0.951903807615","-0.939879759519","-0.927855711423","-0.915831663327","-0.90380761523","-0.891783567134","-0.879759519038","-0.867735470942","-0.855711422846","-0.843687374749","-0.831663326653","-0.819639278557","-0.807615230461","-0.795591182365","-0.783567134269","-0.771543086172","-0.759519038076","-0.74749498998","-0.735470941884","-0.723446893788","-0.711422845691","-0.699398797595","-0.687374749499","-0.675350701403","-0.663326653307","-0.65130260521","-0.639278557114","-0.627254509018","-0.615230460922","-0.603206412826","-0.591182364729","-0.579158316633","-0.567134268537","-0.555110220441","-0.543086172345","-0.531062124248","-0.519038076152","-0.507014028056","-0.49498997996","-0.482965931864","-0.470941883768","-0.458917835671","-0.446893787575","-0.434869739479","-0.422845691383","-0.410821643287","-0.39879759519","-0.386773547094","-0.374749498998","-0.362725450902","-0.350701402806","-0.338677354709","-0.326653306613","-0.314629258517","-0.302605210421","-0.290581162325","-0.278557114228","-0.266533066132","-0.254509018036","-0.24248496994","-0.230460921844","-0.218436873747","-0.206412825651","-0.194388777555","-0.182364729459","-0.170340681363","-0.158316633267","-0.14629258517","-0.134268537074","-0.122244488978","-0.110220440882","-0.0981963927856","-0.0861723446894","-0.0741482965932","-0.062124248497","-0.0501002004008","-0.0380761523046","-0.0260521042084","-0.0140280561122","-0.00200400801603","0.0100200400802","0.0220440881764","0.0340681362725","0.0460921843687","0.0581162324649","0.0701402805611","0.0821643286573","0.0941883767535","0.10621242485","0.118236472946","0.130260521042","0.142284569138","0.154308617234","0.166332665331","0.178356713427","0.190380761523","0.202404809619","0.214428857715","0.226452905812","0.238476953908","0.250501002004","0.2625250501","0.274549098196","0.286573146293","0.298597194389","0.310621242485","0.322645290581","0.334669338677","0.346693386774","0.35871743487","0.370741482966","0.382765531062","0.394789579158","0.406813627255","0.418837675351","0.430861723447","0.442885771543","0.454909819639","0.466933867735","0.478957915832","0.490981963928","0.503006012024","0.51503006012","0.527054108216","0.539078156313","0.551102204409","0.563126252505","0.575150300601","0.587174348697","0.599198396794","0.61122244489","0.623246492986","0.635270541082","0.647294589178","0.659318637275","0.671342685371","0.683366733467","0.695390781563","0.707414829659","0.719438877756","0.731462925852","0.743486973948","0.755511022044","0.76753507014","0.779559118236","0.791583166333","0.803607214429","0.815631262525","0.827655310621","0.839679358717","0.851703406814","0.86372745491","0.875751503006","0.887775551102","0.899799599198","0.911823647295","0.923847695391","0.935871743487","0.947895791583","0.959919839679","0.971943887776","0.983967935872","0.995991983968","1.00801603206","1.02004008016","1.03206412826","1.04408817635","1.05611222445","1.06813627255","1.08016032064","1.09218436874","1.10420841683","1.11623246493","1.12825651303","1.14028056112","1.15230460922","1.16432865731","1.17635270541","1.18837675351","1.2004008016","1.2124248497","1.2244488978","1.23647294589","1.24849699399","1.26052104208","1.27254509018","1.28456913828","1.29659318637","1.30861723447","1.32064128257","1.33266533066","1.34468937876","1.35671342685","1.36873747495","1.38076152305","1.39278557114","1.40480961924","1.41683366733","1.42885771543","1.44088176353","1.45290581162","1.46492985972","1.47695390782","1.48897795591","1.50100200401","1.5130260521","1.5250501002","1.5370741483","1.54909819639","1.56112224449","1.57314629259","1.58517034068","1.59719438878","1.60921843687","1.62124248497","1.63326653307","1.64529058116","1.65731462926","1.66933867735","1.68136272545","1.69338677355","1.70541082164","1.71743486974","1.72945891784","1.74148296593","1.75350701403","1.76553106212","1.77755511022","1.78957915832","1.80160320641","1.81362725451","1.82565130261","1.8376753507","1.8496993988","1.86172344689","1.87374749499","1.88577154309","1.89779559118","1.90981963928","1.92184368737","1.93386773547","1.94589178357","1.95791583166","1.96993987976","1.98196392786","1.99398797595","2.00601202405","2.01803607214","2.03006012024","2.04208416834","2.05410821643","2.06613226453","2.07815631263","2.09018036072","2.10220440882","2.11422845691","2.12625250501","2.13827655311","2.1503006012","2.1623246493","2.17434869739","2.18637274549","2.19839679359","2.21042084168","2.22244488978","2.23446893788","2.24649298597","2.25851703407","2.27054108216","2.28256513026","2.29458917836","2.30661322645","2.31863727455","2.33066132265","2.34268537074","2.35470941884","2.36673346693","2.37875751503","2.39078156313","2.40280561122","2.41482965932","2.42685370741","2.43887775551","2.45090180361","2.4629258517","2.4749498998","2.4869739479","2.49899799599","2.51102204409","2.52304609218","2.53507014028","2.54709418838","2.55911823647","2.57114228457","2.58316633267","2.59519038076","2.60721442886","2.61923847695","2.63126252505","2.64328657315","2.65531062124","2.66733466934","2.67935871743","2.69138276553","2.70340681363","2.71543086172","2.72745490982","2.73947895792","2.75150300601","2.76352705411","2.7755511022","2.7875751503","2.7995991984","2.81162324649","2.82364729459","2.83567134269","2.84769539078","2.85971943888","2.87174348697","2.88376753507","2.89579158317","2.90781563126","2.91983967936","2.93186372745","2.94388777555","2.95591182365","2.96793587174","2.97995991984","2.99198396794","3.00400801603","3.01603206413","3.02805611222","3.04008016032","3.05210420842","3.06412825651","3.07615230461","3.08817635271","3.1002004008","3.1122244489","3.12424849699","3.13627254509","3.14829659319","3.16032064128","3.17234468938","3.18436873747","3.19639278557","3.20841683367","3.22044088176","3.23246492986","3.24448897796","3.25651302605","3.26853707415","3.28056112224","3.29258517034","3.30460921844","3.31663326653","3.32865731463","3.34068136273","3.35270541082","3.36472945892","3.37675350701","3.38877755511","3.40080160321","3.4128256513","3.4248496994","3.43687374749","3.44889779559","3.46092184369","3.47294589178","3.48496993988","3.49699398798","3.50901803607","3.52104208417","3.53306613226","3.54509018036","3.55711422846","3.56913827655","3.58116232465","3.59318637275","3.60521042084","3.61723446894","3.62925851703","3.64128256513","3.65330661323","3.66533066132","3.67735470942","3.68937875752","3.70140280561","3.71342685371","3.7254509018","3.7374749499","3.749498998","3.76152304609","3.77354709419","3.78557114228","3.79759519038","3.80961923848","3.82164328657","3.83366733467","3.84569138277","3.85771543086","3.86973947896","3.88176352705","3.89378757515","3.90581162325","3.91783567134","3.92985971944","3.94188376754","3.95390781563","3.96593186373","3.97795591182","3.98997995992","4.00200400802","4.01402805611","4.02605210421","4.0380761523","4.0501002004","4.0621242485","4.07414829659","4.08617234469","4.09819639279","4.11022044088","4.12224448898","4.13426853707","4.14629258517","4.15831663327","4.17034068136","4.18236472946","4.19438877756","4.20641282565","4.21843687375","4.23046092184","4.24248496994","4.25450901804","4.26653306613","4.27855711423","4.29058116232","4.30260521042","4.31462925852","4.32665330661","4.33867735471","4.35070140281","4.3627254509","4.374749499","4.38677354709","4.39879759519","4.41082164329","4.42284569138","4.43486973948","4.44689378758","4.45891783567","4.47094188377","4.48296593186","4.49498997996","4.50701402806","4.51903807615","4.53106212425","4.54308617234","4.55511022044","4.56713426854","4.57915831663","4.59118236473","4.60320641283","4.61523046092","4.62725450902","4.63927855711","4.65130260521","4.66332665331","4.6753507014","4.6873747495","4.6993987976","4.71142284569","4.72344689379","4.73547094188","4.74749498998","4.75951903808","4.77154308617","4.78356713427","4.79559118236","4.80761523046","4.81963927856","4.83166332665","4.84368737475","4.85571142285","4.86773547094","4.87975951904","4.89178356713","4.90380761523","4.91583166333","4.92785571142","4.93987975952","4.95190380762","4.96392785571","4.97595190381","4.9879759519","5.0"]; setTimeout(function() {
    $('#slider-x0-14').slider({
    	stepping: 1, minValue: 0, maxValue: 499, startValue: 166,
    	change: function () { var position = Math.ceil($('#slider-x0-14').slider('value')); if(values!=null) $('#slider-x0-14-lbl').text(values[position]); interact(14, "sage.server.notebook.interact.update(14, \"x0\", 3, sage.server.notebook.interact.standard_b64decode(\""+encode64(position)+"\"), globals())"); },
    	slide: function() { if(values!=null) $('#slider-x0-14-lbl').text(values[Math.ceil($('#slider-x0-14').slider('value'))]); }
    });
    if(values != null) $('#slider-x0-14-lbl').text(values[Math.ceil($('#slider-x0-14').slider('value'))]);
    }, 1); })();</script></td></tr>
</table><div id='cell-interact-14'><?__SAGE__START>
        <table border=0 bgcolor='#white' width=100% height=100%>
        <tr><td bgcolor=white align=left valign=top><pre><?__SAGE__TEXT></pre></td></tr>
        <tr><td  align=left valign=top><?__SAGE__HTML></td></tr>
        </table><?__SAGE__END></div></td>
                 </tr></table></div>
                 </html>
CPU time: 0.63 s,  Wall time: 2.38 s
}}}

{{{id=97|
%hide

var('u,v')
plots = ['Two Interlinked Tori', 'Star of David', 'Double Heart',
         'Heart', 'Green bowtie', "Boy's Surface", "Maeder's Owl",
         'Cross cap']


plots.sort()

@interact
def _(example=selector(plots, buttons=True, nrows=2),
      tachyon=("Raytrace", True), frame = ('Frame', False),
      opacity=(1,(0.1,1))):
    url = ''
    if example == 'Two Interlinked Tori':
        f1 = (4+(3+cos(v))*sin(u), 4+(3+cos(v))*cos(u), 4+sin(v))
        f2 = (8+(3+cos(v))*cos(u), 3+sin(v), 4+(3+cos(v))*sin(u))
        p1 = parametric_plot3d(f1, (u,0,2*pi), (v,0,2*pi), color="red", opacity=opacity)
        p2 = parametric_plot3d(f2, (u,0,2*pi), (v,0,2*pi), color="blue",opacity=opacity)
        P = p1 + p2
    elif example == 'Star of David':
        f_x = cos(u)*cos(v)*(abs(cos(3*v/4))^500 + abs(sin(3*v/4))^500)^(-1/260)*(abs(cos(4*u/4))^200 + abs(sin(4*u/4))^200)^(-1/200)
        f_y = cos(u)*sin(v)*(abs(cos(3*v/4))^500 + abs(sin(3*v/4))^500)^(-1/260)*(abs(cos(4*u/4))^200 + abs(sin(4*u/4))^200)^(-1/200)
        f_z = sin(u)*(abs(cos(4*u/4))^200 + abs(sin(4*u/4))^200)^(-1/200)
        P = parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, 0, 2*pi),opacity=opacity)
    elif example == 'Double Heart':
        f_x = ( abs(v) - abs(u) - abs(tanh((1/sqrt(2))*u)/(1/sqrt(2))) + abs(tanh((1/sqrt(2))*v)/(1/sqrt(2))) )*sin(v)
        f_y = ( abs(v) - abs(u) - abs(tanh((1/sqrt(2))*u)/(1/sqrt(2))) - abs(tanh((1/sqrt(2))*v)/(1/sqrt(2))) )*cos(v)
        f_z = sin(u)*(abs(cos(4*u/4))^1 + abs(sin(4*u/4))^1)^(-1/1)
        P = parametric_plot3d([f_x, f_y, f_z], (u, 0, pi), (v, -pi, pi),opacity=opacity)
    elif example == 'Heart':
        f_x = cos(u)*(4*sqrt(1-v^2)*sin(abs(u))^abs(u))
        f_y = sin(u) *(4*sqrt(1-v^2)*sin(abs(u))^abs(u))
        f_z = v
        P = parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, -1, 1), frame=False, color="red",opacity=opacity)
    elif example == 'Green bowtie':
        f_x = sin(u) / (sqrt(2) + sin(v))
        f_y = sin(u) / (sqrt(2) + cos(v))
        f_z = cos(u) / (1 + sqrt(2))
        P = parametric_plot3d([f_x, f_y, f_z], (u, -pi, pi), (v, -pi, pi), frame=False, color="green",opacity=opacity)
    elif example == "Boy's Surface":
        url = "http://en.wikipedia.org/wiki/Boy's_surface"
        fx = 2/3* (cos(u)* cos(2*v) + sqrt(2)* sin(u)* cos(v))* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v))
        fy = 2/3* (cos(u)* sin(2*v) - sqrt(2)* sin(u)* sin(v))* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v))
        fz = sqrt(2)* cos(u)* cos(u) / (sqrt(2) - sin(2*u)* sin(3*v))
        P = parametric_plot3d([fx, fy, fz], (u, -2*pi, 2*pi), (v, 0, pi), plot_points = [90,90], frame=False, color="orange",opacity=opacity) 
    elif example == "Maeder's Owl":
        fx = v *cos(u) - 0.5* v^2 * cos(2* u)
        fy = -v *sin(u) - 0.5* v^2 * sin(2* u)
        fz = 4 *v^1.5 * cos(3 *u / 2) / 3
        P = parametric_plot3d([fx, fy, fz], (u, -2*pi, 2*pi), (v, 0, 1),plot_points = [90,90], frame=False, color="purple",opacity=opacity)
    elif example =='Cross cap':
        url = 'http://en.wikipedia.org/wiki/Cross-cap'
        fx = (1+cos(v))*cos(u)
        fy = (1+cos(v))*sin(u)
        fz = -tanh((2/3)*(u-pi))*sin(v)
        P = parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi), frame=False, color="red",opacity=opacity)
    else:
        print "Bug selecting plot?"
        return


    html('<h2>%s</h2>'%example)
    if url:
        html('<h3><a target="_new" href="%s">%s</a></h3>'%(url,url))
    show(P, viewer='tachyon' if tachyon else 'jmol', frame=frame)
///

<html><div padding=6 id='div-interact-97'> <table width=800px height=400px bgcolor='#c5c5c5'
                 cellpadding=15><tr><td bgcolor='#f9f9f9' valign=top align=left><table><tr><td align=right><font color="black">example&nbsp;</font></td><td><table style="border:1px solid #dfdfdf;background-color:#efefef">
<tr><td><button style='border-style:inset;' value='0' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Boy's Surface</button>
<button style='border-style:outset;' value='1' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Cross cap</button>
<button style='border-style:outset;' value='2' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Double Heart</button>
<button style='border-style:outset;' value='3' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Green bowtie</button>
</td></tr>
<tr><td><button style='border-style:outset;' value='4' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Heart</button>
<button style='border-style:outset;' value='5' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Maeder's Owl</button>
<button style='border-style:outset;' value='6' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Star of David</button>
<button style='border-style:outset;' value='7' onclick='$("BUTTON", this.parentNode).css("border-style", "outset"); $(this).css("border-style", "inset"); interact(97, "sage.server.notebook.interact.update(97, \"example\", 4, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.value)+"\"), globals())")'>Two Interlinked Tori</button>
</td></tr></table></td></tr>
<tr><td align=right><font color="black">Raytrace&nbsp;</font></td><td><input type='checkbox' checked width=200px onchange='interact(97, "sage.server.notebook.interact.update(97, \"tachyon\", 5, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.checked)+"\"), globals())")'></input></td></tr>
<tr><td align=right><font color="black">Frame&nbsp;</font></td><td><input type='checkbox'  width=200px onchange='interact(97, "sage.server.notebook.interact.update(97, \"frame\", 6, sage.server.notebook.interact.standard_b64decode(\""+encode64(this.checked)+"\"), globals())")'></input></td></tr>
<tr><td align=right><font color="black">opacity&nbsp;</font></td><td><table><tr><td>
    	<div id='slider-opacity-97' class='ui-slider-3' style='padding:0px;margin:0px;'><span class='ui-slider-handle'></span></div>
    	</td><td><font color='black' id='slider-opacity-97-lbl'></font></td></tr></table><script>(function(){ var values = ["0.100000000000000","0.101803607214429","0.103607214428858","0.105410821643287","0.107214428857715","0.109018036072144","0.110821643286573","0.112625250501002","0.114428857715431","0.116232464929860","0.118036072144289","0.119839679358717","0.121643286573146","0.123446893787575","0.125250501002004","0.127054108216433","0.128857715430862","0.130661322645291","0.132464929859719","0.134268537074148","0.136072144288577","0.137875751503006","0.139679358717435","0.141482965931864","0.143286573146293","0.145090180360721","0.146893787575150","0.148697394789579","0.150501002004008","0.152304609218437","0.154108216432866","0.155911823647295","0.157715430861723","0.159519038076152","0.161322645290581","0.163126252505010","0.164929859719439","0.166733466933868","0.168537074148296","0.170340681362725","0.172144288577154","0.173947895791583","0.175751503006012","0.177555110220441","0.179358717434870","0.181162324649298","0.182965931863727","0.184769539078156","0.186573146292585","0.188376753507014","0.190180360721443","0.191983967935871","0.193787575150300","0.195591182364729","0.197394789579158","0.199198396793587","0.201002004008016","0.202805611222445","0.204609218436873","0.206412825651302","0.208216432865731","0.210020040080160","0.211823647294589","0.213627254509018","0.215430861723446","0.217234468937875","0.219038076152304","0.220841683366733","0.222645290581162","0.224448897795591","0.226252505010020","0.228056112224448","0.229859719438877","0.231663326653306","0.233466933867735","0.235270541082164","0.237074148296593","0.238877755511022","0.240681362725450","0.242484969939879","0.244288577154308","0.246092184368737","0.247895791583166","0.249699398797595","0.251503006012023","0.253306613226452","0.255110220440881","0.256913827655310","0.258717434869739","0.260521042084168","0.262324649298597","0.264128256513025","0.265931863727454","0.267735470941883","0.269539078156312","0.271342685370741","0.273146292585170","0.274949899799598","0.276753507014027","0.278557114228456","0.280360721442885","0.282164328657314","0.283967935871743","0.285771543086172","0.287575150300600","0.289378757515029","0.291182364729458","0.292985971943887","0.294789579158316","0.296593186372745","0.298396793587174","0.300200400801602","0.302004008016031","0.303807615230460","0.305611222444889","0.307414829659318","0.309218436873747","0.311022044088175","0.312825651302604","0.314629258517033","0.316432865731462","0.318236472945891","0.320040080160320","0.321843687374749","0.323647294589177","0.325450901803606","0.327254509018035","0.329058116232464","0.330861723446893","0.332665330661322","0.334468937875750","0.336272545090179","0.338076152304608","0.339879759519037","0.341683366733466","0.343486973947895","0.345290581162324","0.347094188376752","0.348897795591181","0.350701402805610","0.352505010020039","0.354308617234468","0.356112224448897","0.357915831663326","0.359719438877754","0.361523046092183","0.363326653306612","0.365130260521041","0.366933867735470","0.368737474949899","0.370541082164327","0.372344689378756","0.374148296593185","0.375951903807614","0.377755511022043","0.379559118236472","0.381362725450901","0.383166332665329","0.384969939879758","0.386773547094187","0.388577154308616","0.390380761523045","0.392184368737474","0.393987975951902","0.395791583166331","0.397595190380760","0.399398797595189","0.401202404809618","0.403006012024047","0.404809619238476","0.406613226452904","0.408416833667333","0.410220440881762","0.412024048096191","0.413827655310620","0.415631262525049","0.417434869739478","0.419238476953906","0.421042084168335","0.422845691382764","0.424649298597193","0.426452905811622","0.428256513026051","0.430060120240479","0.431863727454908","0.433667334669337","0.435470941883766","0.437274549098195","0.439078156312624","0.440881763527053","0.442685370741481","0.444488977955910","0.446292585170339","0.448096192384768","0.449899799599197","0.451703406813626","0.453507014028054","0.455310621242483","0.457114228456912","0.458917835671341","0.460721442885770","0.462525050100199","0.464328657314628","0.466132264529056","0.467935871743485","0.469739478957914","0.471543086172343","0.473346693386772","0.475150300601201","0.476953907815630","0.478757515030058","0.480561122244487","0.482364729458916","0.484168336673345","0.485971943887774","0.487775551102203","0.489579158316631","0.491382765531060","0.493186372745489","0.494989979959918","0.496793587174347","0.498597194388776","0.500400801603205","0.502204408817633","0.504008016032062","0.505811623246491","0.507615230460920","0.509418837675349","0.511222444889778","0.513026052104206","0.514829659318635","0.516633266533064","0.518436873747493","0.520240480961922","0.522044088176351","0.523847695390780","0.525651302605208","0.527454909819637","0.529258517034066","0.531062124248495","0.532865731462924","0.534669338677353","0.536472945891782","0.538276553106210","0.540080160320639","0.541883767535068","0.543687374749497","0.545490981963926","0.547294589178355","0.549098196392783","0.550901803607212","0.552705410821641","0.554509018036070","0.556312625250499","0.558116232464928","0.559919839679357","0.561723446893785","0.563527054108214","0.565330661322643","0.567134268537072","0.568937875751501","0.570741482965930","0.572545090180358","0.574348697394787","0.576152304609216","0.577955911823645","0.579759519038074","0.581563126252503","0.583366733466932","0.585170340681360","0.586973947895789","0.588777555110218","0.590581162324647","0.592384769539076","0.594188376753505","0.595991983967934","0.597795591182362","0.599599198396791","0.601402805611220","0.603206412825649","0.605010020040078","0.606813627254507","0.608617234468935","0.610420841683364","0.612224448897793","0.614028056112222","0.615831663326651","0.617635270541080","0.619438877755509","0.621242484969937","0.623046092184366","0.624849699398795","0.626653306613224","0.628456913827653","0.630260521042082","0.632064128256510","0.633867735470939","0.635671342685368","0.637474949899797","0.639278557114226","0.641082164328655","0.642885771543084","0.644689378757512","0.646492985971941","0.648296593186370","0.650100200400799","0.651903807615228","0.653707414829657","0.655511022044086","0.657314629258514","0.659118236472943","0.660921843687372","0.662725450901801","0.664529058116230","0.666332665330659","0.668136272545087","0.669939879759516","0.671743486973945","0.673547094188374","0.675350701402803","0.677154308617232","0.678957915831661","0.680761523046089","0.682565130260518","0.684368737474947","0.686172344689376","0.687975951903805","0.689779559118234","0.691583166332662","0.693386773547091","0.695190380761520","0.696993987975949","0.698797595190378","0.700601202404807","0.702404809619236","0.704208416833664","0.706012024048093","0.707815631262522","0.709619238476951","0.711422845691380","0.713226452905809","0.715030060120238","0.716833667334666","0.718637274549095","0.720440881763524","0.722244488977953","0.724048096192382","0.725851703406811","0.727655310621239","0.729458917835668","0.731262525050097","0.733066132264526","0.734869739478955","0.736673346693384","0.738476953907813","0.740280561122241","0.742084168336670","0.743887775551099","0.745691382765528","0.747494989979957","0.749298597194386","0.751102204408814","0.752905811623243","0.754709418837672","0.756513026052101","0.758316633266530","0.760120240480959","0.761923847695388","0.763727454909816","0.765531062124245","0.767334669338674","0.769138276553103","0.770941883767532","0.772745490981961","0.774549098196390","0.776352705410818","0.778156312625247","0.779959919839676","0.781763527054105","0.783567134268534","0.785370741482963","0.787174348697391","0.788977955911820","0.790781563126249","0.792585170340678","0.794388777555107","0.796192384769536","0.797995991983965","0.799799599198393","0.801603206412822","0.803406813627251","0.805210420841680","0.807014028056109","0.808817635270538","0.810621242484966","0.812424849699395","0.814228456913824","0.816032064128253","0.817835671342682","0.819639278557111","0.821442885771540","0.823246492985968","0.825050100200397","0.826853707414826","0.828657314629255","0.830460921843684","0.832264529058113","0.834068136272542","0.835871743486970","0.837675350701399","0.839478957915828","0.841282565130257","0.843086172344686","0.844889779559115","0.846693386773543","0.848496993987972","0.850300601202401","0.852104208416830","0.853907815631259","0.855711422845688","0.857515030060117","0.859318637274545","0.861122244488974","0.862925851703403","0.864729458917832","0.866533066132261","0.868336673346690","0.870140280561118","0.871943887775547","0.873747494989976","0.875551102204405","0.877354709418834","0.879158316633263","0.880961923847692","0.882765531062120","0.884569138276549","0.886372745490978","0.888176352705407","0.889979959919836","0.891783567134265","0.893587174348694","0.895390781563122","0.897194388777551","0.898997995991980","0.900801603206409","0.902605210420838","0.904408817635267","0.906212424849695","0.908016032064124","0.909819639278553","0.911623246492982","0.913426853707411","0.915230460921840","0.917034068136269","0.918837675350697","0.920641282565126","0.922444889779555","0.924248496993984","0.926052104208413","0.927855711422842","0.929659318637270","0.931462925851699","0.933266533066128","0.935070140280557","0.936873747494986","0.938677354709415","0.940480961923844","0.942284569138272","0.944088176352701","0.945891783567130","0.947695390781559","0.949498997995988","0.951302605210417","0.953106212424846","0.954909819639274","0.956713426853703","0.958517034068132","0.960320641282561","0.962124248496990","0.963927855711419","0.965731462925847","0.967535070140276","0.969338677354705","0.971142284569134","0.972945891783563","0.974749498997992","0.976553106212421","0.978356713426849","0.980160320641278","0.981963927855707","0.983767535070136","0.985571142284565","0.987374749498994","0.989178356713422","0.990981963927851","0.992785571142280","0.994589178356709","0.996392785571138","0.998196392785567","0.999999999999996"]; setTimeout(function() {
    $('#slider-opacity-97').slider({
    	stepping: 1, minValue: 0, maxValue: 499, startValue: 499,
    	change: function () { var position = Math.ceil($('#slider-opacity-97').slider('value')); if(values!=null) $('#slider-opacity-97-lbl').text(values[position]); interact(97, "sage.server.notebook.interact.update(97, \"opacity\", 7, sage.server.notebook.interact.standard_b64decode(\""+encode64(position)+"\"), globals())"); },
    	slide: function() { if(values!=null) $('#slider-opacity-97-lbl').text(values[Math.ceil($('#slider-opacity-97').slider('value'))]); }
    });
    if(values != null) $('#slider-opacity-97-lbl').text(values[Math.ceil($('#slider-opacity-97').slider('value'))]);
    }, 1); })();</script></td></tr>
</table><div id='cell-interact-97'><?__SAGE__START>
        <table border=0 bgcolor='#white' width=100% height=100%>
        <tr><td bgcolor=white align=left valign=top><pre><?__SAGE__TEXT></pre></td></tr>
        <tr><td  align=left valign=top><?__SAGE__HTML></td></tr>
        </table><?__SAGE__END></div></td>
                 </tr></table></div>
                 </html>
CPU time: 0.02 s,  Wall time: 0.64 s
}}}

{{{id=96|

///
}}}

{{{id=22|

///
}}}

<hr>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>




<center<h1>Lickable 3D Graphics in Sage</h1></center>


<font size=+1>
<table bgcolor="#eaeaea" align=center cellpadding=20 width=50% border=1><tr><td>
<ol>
<li> Background
<li> Cape Man
<li> Platonic Polytopes
<li> Parametric Plots
<li> List Plots
</ol>
</td></tr></table>
</font>

<br><br>
<hr>
<font color='black'><h1  align=center>Background</h1></font>
<br><br><br>

Robert Bradshaw and I added systematic 3d graphics support to Sage in January 2008, 
so 3d graphics are fairly new in Sage.
Nonetheless, they are very useful. 

<ol>
<li> Sage 3d graphics are built up from <b>three components</b>:
<ol> 
<li> <b>User Interface:</b> (my talk today) Python functions with lots of options that users directly call to easily create 3d scenes.
(I wrote most of this.)
<br><br>
<li> <b>3d "Subsystem":</b> (Robert Bradshaw's talk today) A cython library that converts the wishes of the user into low-level
primitives that make sense to various rendering systems.  This is where a lot of the interesting mathematics is.
(Robert Bradshaw wrote most of this.)
<br><br>
<li> <b>Rendering System:</b> Program that displays or renders an image expressed in some standard format, e.g., an X3d viewer,
a ray tracer, or a java applet. 
</ol>
<br><br>

<li> Sage mainly uses two systems to render 3d graphics, though other options are supported:
<ol>
<li> <a href="http://jedi.ks.uiuc.edu/%7Ejohns/raytracer/">Tachyon3d</a> -- a lightweight BSD-licensed multithreaded ray tracer.  This is good because it is essentially the <b>only</b> fully open source program we could find that doesn't require an X server and quickly renders 3d images as png's. 
<br><br>

<li> <a href="http://jmol.sourceforge.net/">Jmol: an open-source Java viewer for chemical structures in 3D</a> -- this was meant for molecular visualization, but we adapted it for Sage.  It is GPL licensed.  Here is <a target="_new" href="http://jmol.sourceforge.net/demo/vibration/">an example of the sort of thing jmol can do, and which Sage could <i>certainly</i> do given some effort</a>. 

</ol>
<br><br>

<li> <b>Mayavi -- The High End Option for OpenGL-based 3d graphics in Sage/Python</b>
 <a href="http://mayavi.sourceforge.net/" target="_new">Mayavi / vtk</a> -- this is a powerful high-end setup for doing 3d accelerated graphics with Python.  It doesn't work over the web at all, but <i>does</i> take advantage of fast 3d accelerated graphics cards and can render very large data sets.  I don't use it, but many people do.   There are <a href="http://sagemath.org/packages/experimental/">experimental packages here</a> that
might allow you to easily build this visualization stack into Sage.   <b>Possible student project:</b> test those packages, update them, get them
up to "optional" quality. 
<ol>


<br><br>
<br><br>
<br><br><br><br>
<br><br>
<br><br>
<hr>

<font color='black'><h1  align=center>Demo: Cape Man</h1></font>
<br><br><br>

{{{id=57|
# Draw a nice yellow sphere, which is a basic primitive
S = sphere(size=50, color='yellow')
S.show(viewer='tachyon')
///
}}}

{{{id=58|
# Get rid of the default frame and make red...
# All options to sphere that aren't specifically for a sphere get passed on to
# the show command, and also get carried along when you add objects with +. 
# This was a convenience I added for 3d graphics.  It's not in 2d graphics.
# Someone could implement this...
S = sphere(size=.5, color=(1,0,0),    frame=False)
S   # show using jmol
///
}}}

{{{id=59|
# There are a bunch more primitive shapes that you can see using sage.plot.plot3d.shapes.[tab]
C = sage.plot.plot3d.shapes.Cone(.5, .5, color='red')
C
///
}}}

{{{id=60|
# You can move a shape around (notice the z axis range below)
C = C.translate(0,0,0.3)   # (dx,dy,dz)
C   # this is now moved up.
///
}}}

{{{id=61|
# We can draw a bunch of sphere's with different colors and sizes
balls = sphere((.45,-.1,.15), size=.1, color='white') + sphere((.51,-.1,.17), size=.05, color='black')
balls += sphere((.45, .1,.15),size=.1, color='white') + sphere((.51, .1,.17), size=.05, color='black')
balls += sphere((.5,0,-.2),size=.1, color='yellow', aspect_ratio=[1,1,1], frame=False)
balls
///
}}}

{{{id=62|
# We plot a symbolic expression that is a function of two variables.
# Notice that the default frame is not a cube, i.e., not as tall as
# it is wide.  This just copies the default used in other Ma's, which
# is convenient for plotting functions.

var('x,y')
f = exp(x/5) * cos(y)
P = plot3d(f,(x,-5,5),(y,-5,5), adaptive=True, color=['red','yellow'])
P
///
}}}

{{{id=63|
# Now we combine all the above plots together in one image
cm = P.scale(.2) + (balls + C + S).translate(1,0,0)
cm.show(spin=True, zoom=1.1)
///
}}}

{{{id=3|

///
}}}

{{{id=64|

///
}}}

{{{id=5|

///
}}}

<br><br>
<br><br>
<br><br><br><br>
<br><br>
<br><br>
<hr>

<font color='black'><h1 align=center>Platonic Polytopes</h1></font>
<br><br><br>

{{{id=99|
tetrahedron()
///
}}}

{{{id=7|
show(cube(color=['red', 'blue', 'green'], frame_thickness=15, \
                       frame_color='brown', opacity=0.7), frame=False)
///
}}}

{{{id=73|

///
}}}

{{{id=74|

///
}}}

<br><br>
<br><br>
<br><br><br><br>
<br><br>
<br><br>
<hr>

<font color='black'><h1  align=center>Lines, Text, Frames, Points,  </h1></font>
<br><br><br>

{{{id=76|
line3d([(1,2,3), (1,0,-2), (3,1,4), (2,1,-2)], color='red')
///
}}}

{{{id=77|
def tetra(col): 
    return line3d([(0,0,1), (2*sqrt(2.)/3,0,-1./3), (-sqrt(2.)/3, sqrt(6.)/3,-1./3),\ 
    (-sqrt(2.)/3,-sqrt(6.)/3,-1./3), (0,0,1), (-sqrt(2.)/3, sqrt(6.)/3,-1./3),\
    (-sqrt(2.)/3,-sqrt(6.)/3,-1./3), (2*sqrt(2.)/3,0,-1./3)],\
    color=col, thickness=10, aspect_ratio=[1,1,1])

v  = (sqrt(5.)/2-5/6, 5/6*sqrt(3.)-sqrt(15.)/2, sqrt(5.)/3)
t  = acos(sqrt(5.)/3)/2
t1 = tetra('blue').rotateZ(t)
t2 = tetra('red').rotateZ(t).rotate(v,2*pi/5)
t3 = tetra('green').rotateZ(t).rotate(v,4*pi/5)
t4 = tetra('yellow').rotateZ(t).rotate(v,6*pi/5)
t5 = tetra('orange').rotateZ(t).rotate(v,8*pi/5)
show(t1+t2+t3+t4+t5, frame=False, zoom=1.3)
///
}}}

{{{id=39|
v = finance.fractional_brownian_motion_simulation(0.8,0.01,1000,3)
# in sage-3.0.6 there is a bug so do
# v = [a.sums() for a in v]
line3d([(v[0][i],v[1][i],v[2][i]) for i in range(len(v[0]))], color='black')
///
}}}

{{{id=38|
sum(text("Hi, from Scipy 2008 %s"%i, (i^2,i,i^3), color=(1-i/9,0,i/9)) for i in [1..5])
///
}}}

{{{id=36|

///
}}}

{{{id=78|

///
}}}

{{{id=11|

///
}}}

<br><br>
<br><br>
<br><br><br><br>
<br><br>
<br><br>
<hr>
<font color='darkgreen'><h1 align=center>3D Parametric Plots</h1></font>

{{{id=47|
var('u')
parametric_plot3d( (sin(u), cos(u), u/10), (u, 0, 20))
///
}}}

{{{id=45|
var('u,v')
fx = (3*(1+sin(v)) + 2*(1-cos(v)/2)*cos(u))*cos(v)
fy = (4+2*(1-cos(v)/2)*cos(u))*sin(v)
fz = -2*(1-cos(v)/2) * sin(u)
parametric_plot3d([fx, fy, fz], (u, 0, 2*pi), (v, 0, 2*pi), frame=False, color="green", opacity=.7)
///
}}}

{{{id=44|

///
}}}

{{{id=80|

///
}}}

{{{id=35|

///
}}}

<font color='darkgreen'><h1 align=center>3D List Plots</h1></font>

{{{id=48|
pi = float(pi)
m = matrix(RDF, 6, [sin(i^2 + j^2) for i in [0,pi/5,..,pi] for j in [0,pi/5,..,pi]])
list_plot3d(m, texture='yellow', frame_aspect_ratio=[1,1,1/3])
///
}}}

{{{id=52|
# Lets try a spline interpolation type.
list_plot3d(m, texture='yellow', interpolation_type='spline',frame_aspect_ratio=[1,1,1/3], degree=5)
///
}}}

{{{id=41|
# Note that the points do not have to be regularly sampled. For example

l=[]
for i in range(-5,5):
    for j in range(-5,5):
        l.append((normalvariate(0,1),normalvariate(0,1),normalvariate(0,1)))
       
list_plot3d(l,interpolation_type='nn',texture='yellow',num_points=100)
///
}}}

{{{id=42|

///
}}}

{{{id=43|

///
}}}

{{{id=54|

///
}}}

{{{id=55|

///
}}}

{{{id=82|

///
}}}

<hr>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>



<!--


<center<h1>An Application: Random Walks</h1></center>



<font size=+1>
<table bgcolor="#eaeaea" align=center cellpadding=20 width=50% border=1><tr><td>
<ol>
<li> 1-d Random Walks
<li> 2-d Random Walks
<li> 3-d Random Walks
<li> Random Walks on a Surface
</ol>
</td></tr></table>
</font>

{{{id=84|

///
}}}

<hr>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>

<center><h1>Polynomial Equations</h1></center>

<table bgcolor="#eaeaea" align=center cellpadding=20 width=50% border=1><tr><td>
<ol>
<li> Univariate polynomial root finding
<li> Finding roots symbolically 
<li> Real root isolation
<li> Solving $F(X,Y)=G(X,Y)=0$.
</ol>
</td></tr></table>

{{{id=86|

///
}}}

<hr>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>
<br><br>

<center><h1>Some Cutting Edge Number Theory: Elliptic Curves</h1></center>
<table bgcolor="#eaeaea" align=center cellpadding=20 width=50% border=1><tr><td>
<ol>
<li> Definition of elliptic curves
<li> Group structure and rank
<li> Points modulo a prime
<li> The Million-Dollar Birch and Swinnerton-Dyer Conjecture
</ol>
</td></tr></table>

{{{id=88|

///
}}}

-->

{{{id=90|

///
}}}