This HTML document is based on Mathematica Graphics: An Intensive Tutorial by Tom WickhamJones. It was adapted by Martin Kraus for noncommercial use.
Mathematica and MathLink are registered trademarks, and MathReader, MathSource and 3Script are trademarks of Wolfram Research, Inc.
All other product names mentioned are trademarks of their producers.
Copyright 1992 by Wolfram Research, Inc.
All rights reserved. No part of this document may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, photocopying, recording or otherwise, without the prior written permission of the copyright holder.
Having seen how to construct functions for builtin commands we can go further and build our own graphics commands. Commands such as Plot evaluate their input function over a range and construct a collection of graphics primitives. We could do something very similar. Of course it would not be so useful to reproduce the actual builtin commands. However there are many other tasks to be tackled by writing in the Mathematica programming language. Here we shall look at some possibilities.
The first idea comes from iteration. If one repeatedly applies a function, the values returned in some cases converge to a fixed point and in others to seemingly random and complex behavior. For example, consider a function such as 4x(1  x).
Floatingpoint numbers are used to ensure real arithmetic.  In[1]:= fun[x_] := 4. x (1.  x) 
This is the value for an argument of .25.  In[2]:= fun[0.25] Out[2]= 0.75 
This gives me four iterations of fun.  In[3]:= fun[fun[fun[fun[0.25]]]] Out[3]= 0.75 
Of course Mathematica gives a much neater way to apply this function repeatedly.  In[4]:= Nest[fun, 0.25, 10] Out[4]= 0.75 
NestList keeps the intermediate values.  In[5]:= NestList[fun, 0.25, 10] Out[5]= {0.25, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75, 0.75} 
Now we can change the starting point and we see the function does not converge anymore.  In[6]:= NestList[fun, 0.24, 10] Out[6]= {0.24, 0.7296, 0.789135, 0.665603, 0.890303, 0.390655, 0.952175, 0.182151, 0.595887, 0.963222, 0.1417} 
Very nice, but I want to see a graphical representation of this. To do this I shall write some code. The function is being applied to some point, and the value which results is used as the next starting point. We are thus interacting with the line <x,x> and we are interested in the two lines <x,x> and <x,f[x]>.
These are the two lines we are interested in.  In[7]:= plot = ParametricPlot3D[{{0, x, x},
{0, x, fun[x]}}, {x, 0, 1}] 
Out[7]=  Graphics3D  

This function collects all the steps which we have carried out. It takes two arguments and returns a Graphics3D object.  In[8]:= Iterate[st_, n_] := Block[{res}, res = NestList[fun, st, n]; res = Flatten[Transpose[{res, res}]]; res = Partition[res, 2, 1]; res = Transpose[Prepend[Transpose[res], Table[i / n, {i, 0, 2 n}]]]; Graphics3D[Line[res]]] 
In[9]:= Iterate[.4, 20] Out[9]=  Graphics3D  

This combines the result.  In[10]:= Show[plot, %, ViewPoint > {100, 0, 0}] 
Out[10]=  Graphics3D  
In a few lines of code we have a useful way to explore these iterated procedures. This function Iterate could be extended to take the iterated function as an argument and also to generate all the plots automatically.
Mathematica graphics provide many primitives for plotting. However there may be some primitive which you desire but which is not present. Instead of saying "if only they had..." why not actually write it. Here we shall look at an example of building a new primitive out of existing ones to draw arrows in three dimensions.
This defines some options for our threedimensional arrow.  In[11]:= Options[Arrow3D] = {HeadLength > 0.3,
HeadNormal > {0, 0, 1}, HeadWidth > 0.5}; 
This definition of Arrow3D shows the standard way to use options in Mathematica.  In[12]:= Arrow3D[a_, b_, opts___] := Module[{abLength = N[Sqrt[(b  a) . (b  a)]], abUnit, headPerp, headPerpLength, headLength, headNormal, headWidth}, {headLength, headNormal, headWidth} = {HeadLength, HeadNormal, HeadWidth} /. {opts} /. Options[Arrow3D]; abUnit = (b  a) / abLength; headPerp = Cross[abUnit, N[headNormal]]; headPerp = headPerp / Sqrt[N[headPerp.headPerp]]; {Line[{a, b  abUnit * headLength}], Polygon[{b, b  abUnit * headLength + headPerp * headWidth / 2 * headLength, b  abUnit * headLength, b  abUnit * headLength  headPerp * headWidth / 2 * headLength}]}]; 
Arrow3D evaluates to a list of graphics primitives.  In[13]:= Arrow3D[{0, 0, 0}, {1, 1, 1}] Out[13]= {Line[{{0, 0, 0}, {0.826795, 0.826795, 0.826795}}], Polygon[{{1, 1, 1}, {0.879828, 0.773762, 0.826795}, {0.826795, 0.826795, 0.826795}, {0.773762, 0.879828, 0.826795}}]} 
Now we can use Arrow3D in Graphics3D objects like other primitives.  In[14]:= Show[Graphics3D[{
Arrow3D[{0, 0, 0}, {1, 0, 0}],
Arrow3D[{1, 0, 0}, {1, 1, 1}],
Arrow3D[{0, 0, 0}, {1, 1, 1}]}]] 
Out[14]=  Graphics3D  
no further pages  back to table of contents 