Function Plotting


Cinderella provides several operators that allow one to plot information about mathematical functions. Besides simple function plotting, information on extrema, zeros, and inflection points can be shown.




Plotting a Function plot(<expr>):


Description: The plot operator can be used to plot a function. The function must be given as an expression <expr>. This expression must contain the running variable # and calculate either a real value for a real input of # or a two-dimensional vector. In the first case, the plot operator will simply draw the function. In the latter case, it will draw a parametric plot of a function. The coordinate system is tied to the coordinate system of the geometric views.

Examples: In its simplest form the plot operator can be used directly to plot a function. The line plot(sin(#)) immediately plots the function sin(x).



Similarly, one can first define a function whose graph is then displayed by the plot operator. It is important that the running variable used in the plot operator be #. The following lines of code produce the picture below:

f(x):=1/(x^2+1)*sin(4*x);
plot(f(#));




If invoked with an expression <expr> that produces a two-dimensional vector as output, the plot operator will automatically generate a parametric plot of a curve. Here the value range for the input variable is taken by default to be from 0 to 100. However, these defaults can easily be changed by modifiers. The line plot((sin(#),cos(#))*#) produces the following output:



Modifiers: The plot operator admits many different modifiers. Some of them have to be explained in detail. They can be used to modify the appearance of the curve, to modify the plot range, to modify the position on the screen, and even to display maxima, minima, zeros, and inflection points of the function. An overview of available modifiers is given in the table below. Observe that some of the modifiers may even be invoked with different types of arguments, resulting in a slightly different effect.

modifier: argument type: effect
appearance:
color[<real1>,<real2>,<real3>]set color to specific value
size<real>set line size to specific value
alpha<real>set opacity
iteration control:
start<real>set start value for function drawing
stop<real>set end value for function drawing
steps<real>number of set plot points (for parametric functions only)
pxlres<real>pixel resolution of curve plotting (for real functions only)
significant points:
extrema<bool>mark all extrema
extrema[<real1>,<real2>,<real3>]mark all extrema in specified color
minima<bool>mark all minima
minima[<real1>,<real2>,<real3>]mark all minima in specified color
maxima<bool>mark all maxima
maxima[<real1>,<real2>,<real3>]mark all maxima in specified color
zeros<bool>mark all zeros
zeros[<real1>,<real2>,<real3>]mark all zeros in specified color
inflections<bool>mark all inflection points
inflections[<real1>,<real2>,<real3>]mark all inflection points in specified color


Examples: Here are a few examples that demonstrate the use of the modifiers:

One can easily vary the plot range by setting the start and stop values.
For instance, plot(f(#),start->A.x,stop->B.x) helps to control the plot using by the x-coordinates of two free construction points.



Sometimes it is useful to calculate fewer plot points (if the function is computationally expensive) or more plot points (if one needs higher resolution). The density of plot points can be controlled by the pxlres modifier. The statement pxlres->1 means one plot point per pixel. In some rare cases it might even be helpful to set the pxlres parameters to values below 1 pixel, as the example below demonstrates.

plot(sin(1/#)*#)plot(sin(1/#)*#,alpha->0.2,pxlres->0.1)


By using the modifiers for a curve's significant points one can display zeros, minima, maxima, and inflection points. The following three pictures demonstrate the use of these operators.

zeros->true
extrema->true
inflections->true


The color and the alpha modifiers are implemented in a way that allows for setting colors and opacity values that depend on the input variable #. This allows for encoding a further level of graphical information into function plots. An easy example is given by the following lines of code:

plot(sin(#),
   color->hue(#/(2*pi)),
   size->2
)







Colorfields colorplot(<expr>,<vec>,<vec>):



Description: The colorplot operator makes it possible to give a visualization of a planar function. To each point of a rectangle a color value can be assigned by a function. In the function <expr> the running variable is again #. However, it is important to notice that this variable is now a two-dimensional vector. The return value of <expr> should be either a real number (in which case a gray value is assigned) or a vector of three real numbers (in which case an RGB color value is assigned). In any case, the values of the real numbers should lie between 0 and 1. The second and third argument determine the lower left and the upper right corners of the drawing area.

Example: The following code and two points A and B produce the picture below. In the first line, a real-valued function is defined that assigns to two points the sine of the distance between them (shifted and scaled to fit into the interval 0, 1external link). The first argument of the colorplot operator is now a vector of three numbers depending on the run variable # (the red part is a circular wave around A, the green part is zero, and the blue part is a circular wave around B). Finally, C and D mark the corners of the rectangle.

f(A,B):=((1+sin(2*dist(A,B)))/2);
colorplot(
   (f(A,#),0,f(B,#)),
   C,D
)




Modifiers: The colorplot operator admits three modifiers. The modifier pxlres can be set to an integer that determines the size in pixels of the elementary quadrangles of the color plot. The picture below was taken with pxlres->2. Setting the pxlres modifier either to 1 or to 2 produces stunning pictures. However, one should be aware that for each elementary quadrangle of the colorplot output the function has to be evaluated once. The computational effort grows quadratically as pxlres is linearly reduced. We added another modifier startres that can be used to have gradually improving plots, thus combining the best of two worlds. For example, using both startres->32 and pxlres->1 you will get a coarse plot during interactive movements, which will be re-calculated automatically with a finer resolution whenever there is enough time.



Furthermore, the colorplot operator admits a modifier alpha that is used to control the opacity. This modifier can even be set to values that depend parametrically on the running variable.

The picture below was generated by the following code, which is only a slight modification of the code of the last example:

f(A,B):=((1+sin(2*dist(A,B)))/2);
colorplot(
   (f(A,#),0,f(B,#)),
   C,D,
   pxlres->2,
   alpha->-abs(#)+5
)







Drawing a vector field drawfield(<expr>):


Description: The drawfield operator can be used to draw a vector field. The function must be given as an expression <expr>. This expression must contain the running variable #, which should this time be a two-dimensional vector. The result should also be a two-dimensional vector. Applying the operator drawfield to this expression will result in plotting the corresponding vector field. The field will be animated. This means that it will change slightly with every picture. Therefore, it is often useful to put the drawfield operator into the "timer tick" evaluation slot. This creates an animation control in the geometric view. Running the animation will automatically animate the vector field. In the drawfield operator the run variable for the function <expr> must be the # variable.

Examples: We consider a vector field defined by the function f(x,y)=(y,sin(x)). The corresponding code with the function definition and the call of the drawfield operator is as follows:

f(v):=[v.y,sin(v.x)];
drawfield(f(#));




To generate the picture, a collection of needlelike objects is thrown onto the drawing surface. These needles will be oriented according to the vector field. During the animation, the needles move according to the vector field. It is also possible to replace the needles by small snakelike objects that give a more accurate impression of the vector field but take a longer time for calculation. This can be done with a suitable modifier.

f(v):=[v.y,sin(v.x)];
drawfield(f(#),stream->true);




Modifiers: The drawfield operator possesses many modifiers that control the generation process of the vector field. To help in understanding them we first describe in a bit more detail how the pictures are generated.

The pictures are generated by showing the movement of some test objects under the influence of the field. By default, the test objects are needlelike. They are initially positioned on a regular grid. Since this usually creates many visual artifacts, they are randomly distorted within a certain radius around the grid points. During an animation the needles are moved in the direction of the force field. The needles' lengths represent the strength of the field.

modifier:argument type:effect
test objects:
resolutionintegeroriginal grid cell size in pixels
jitterintegerdistortion of the test objects
needlesize<real>maximum size of the needles
factor<real>scaling factor of the field strength
stream<bool>use needles or streamlets
move<real>speed of moving objects
appearance:
color[<real1>,<real2>,<real3>]set streamlet color or first needle color
color2[<real1>,<real2>,<real3>]set second needle color


The following picture demonstrates the original grid. It has been rendered with move->0 and jitter->0. It shows clear artifacts resulting from unnatural alignment in the horizontal or vertical direction.



The following picture has been rendered with resolution->5 and stream->true.






Drawing a complex vector field drawfieldcomplex(<expr>):


Description: This operator is very similar to the +drawfield+- operator. However, it takes as input a one-dimensional complex function. The real and imaginary parts are treated as x and y components for the vector field. Otherwise, the operator is completely analogous to the previous one.

Example: The following example demonstrates the use of the operator with a complex polynomial whose zeros are determined by four points in the drawing:

f(x):=(x-complex(A))*(x-complex(B))*(x-complex(C))*(x-complex(D));
drawfieldcomplex(f(#),stream->true,resolution->5,color->(0,0,0))





The modifiers are analogous to those for the drawfield operators.




Drawing a force field drawforces():


Description: This operator is again very similar to the drawfield operator. However, this time it is related to a physics simulation in CindyLab. No arguments are required, and it shows the forces on a potential test charge that is placed at various locations on the screen. The test charge has mass = 1, charge = 1, and radius = 1. However, no other particle will interact with it. Sometimes it will be necessary to use the factor modifier to amplify the force field. The following example shows the interaction among four charged particles.






Drawing the force field of a point drawforces(<mass>):


Description: There is another operator that draws the force field with respect to a fixed mass particle. The particle itself takes no part in the calculation of the forces. In this way, one can visualize the forces that act on a certain particle.







Curve drawing of physics magnitudes drawcurves(<vec>,<list>):


Description: In real and simulated physical situations one is often interested in plotting curves that show how magnitudes evolve over time. For this, the drawcurves operator was created. Here <vec> is a two-dimensional vector that refers to the lower left corner of the drawing area, and <list> is a list of values that are to be observed. When the animation runs, the values are updated and the corresponding curves are drawn.

Example: The next picture shows a very simple application of the drawcurves operator. In CindyLab, a physical pendulum was constructed. The following code produces a curve plot of the x coordinate of the moving point and of its x velocity:

drawcurves([0,0],[D.x,D.vx])




Modifiers: The drawcurves operator possesses many modifiers. Than can be used to change the appearance of the curves and to show additional information.

modifier:argument type:effect
dimension:
width<real>pixel width of the plot range
height<real>pixel height for each curve
appearace:
border<bool>show the borders of the table
back<bool>show a background
back[<real1>,<real2>,<real3>]show background in specified color
backalpha<real>opacity of background
colors[<col1>,<col2>,<col3>,...]provide a color for each curve
information:
texts[<text1>,<text2>,<text3>,...]provide a caption for each curve
showrange<bool>show the max and min values for each curve
rendering:
range<string>"peek" scales to the absolute measured maximum, "auto" scales to the currently shown part of the curve
range[<string1>,<string1>,<string1>,...]individual "peek"/"auto" for each curve


The following piece of code demonstrates the usage of the modifiers. It shows a weakly coupled pendulum and its energy behavior.

linecolor((1,1,1));
textcolor((0,0.8,0));
drawcurves((-7,-3),
  [A.x,B.x,A.ke,B.ke,a.pe+b.pe+c.pe],
  height->50,
  color->(1,1,1),
  back->(0,0,0),
  backalpha->1,
  range->"peek",width->400,
  colors->[
    [1,0.5,0.5],
    [0.5,1,0.5],     
    [1,0.5,0.5], 
    [0.5,1,0.5],
    [0.5,0.5,1]],
  texts->[
    "PosA = "+ A.x,
    "PosB = "+B.x,
    "EnergyA = "+A.ke,
    "EnergyB = "+B.ke,
    "PotentialEnergy = "+(a.pe+b.pe+c.pe)
]
);


The corresponding drawing looks as follows:






Page last modified on Monday 03 of September, 2007 [20:11:54 UTC].
The original document is available at http://doc.cinderella.de/tiki-index.php?page=Function%20Plotting