You are here

Constructing Mathlets Quickly using LiveGraphics3D - Parametrized Graphics

Jonathan Rogness and Martin Kraus

So far all of our graphics primitives have had fixed, precomputed numbers as coordinates. One of LiveGraphics3D's most powerful features is its ability to display primitives whose coordinates are not fixed, but depend on independent variables which can be adjusted by the user. These objects are referred to as parametrized graphics.

As a basic example, consider the primitive Point[{x,0,0}] and suppose the initial value of x is 0. LiveGraphics3D would display this as a point at the three-dimensional origin, but you could click on the point and drag it to any location on the x-axis. As the point is dragged, the value of x would be adjusted accordingly. Any other primitives -- points, lines, polygons or text -- whose coordinates depend on x would be redrawn.

Now let's use this idea to continue building our example. First we add a point to our input file as follows.

(* "mesh" is the same as in the previous example *)
point = {RGBColor[1, 0, 0], PointSize[0.02], Point[{x, y, z}]};

example = Graphics3D[{mesh, point}, Boxed -> False];
WriteLiveForm["meshPoint.lg3d", example]

Because the coordinates in Point[{x,y,z}] are not fixed numbers, we need to tell LiveGraphics3D how to compute them at runtime. There is a fundamental difference here between z and the other two variables. x and y are independent variables; after specifying their initial values, we want to be able to change them by moving the point. Conversely, z is a dependent variable whose value should always be calculated using the formula for f(x, y).

This information is passed to the applet using the INDEPENDENT_VARIABLES and DEPENDENT_VARIABLES parameters. The value for either of these parameters is a list of rules LiveGraphics3D can use to assign values to variables. In the case of independent variables each rule just gives the initial value, which can later be changed by the user. The rules for dependent variables describe how to compute the values using any other previously mentioned variables.

Resulting applet:

Click and drag the red point to see how it moves along the surface. The effect of defining z as a dependent variable is quite noticeable in the following sense: if you view the surface from above, the motion of the point is quite natural; motions of the mouse correspond directly to changes in x and y. If you view the surface from the side, however, the point is very tricky to control.

By now you may have noticed that you can drag the point off of the mesh. This undesirable behavior can be avoided with a feature that is tricky and counter-intuitive, yet highly useful: rules for independent variables can also appear in the value of the DEPENDENT_VARIABLESparameter. This is demonstrated in the following HTML code. We use the same input file as above, together with a new set of rules for dependent variables which restrict the values of x and y so that the point stays on the mesh.

To understand how this process works, suppose you move the point with the mouse. Internally, LiveGraphics3D will recognize that an independent variable has been changed. Whenever this happens, the rules in the DEPENDENT_VARIABLESparameter will be evaluated in order. Each of the Ifstatements below restricts the value of a variable; for example, the statement x -> If[x < -1, -1, x]sets x=-1if you have dragged it to a value less than -1, and leaves it unchanged otherwise. The new value of z is only computed after the rules for x and y have been processed, ensuring that the point will be on our mesh.

Resulting applet:

Before continuing, we should mention the following issues related to this example.

  1. A Point can only be dragged if at least one of its coordinates is an independent variable; if we replaced Point[{x,y,z}] in the input file with Point[{x/2,y/2,z}] -- or even Point[{1*x,1*y,z}] -- LiveGraphics3D would not allow us to click on it. (In the latter case, 1*x and 1*y are certainly equivalent to x andy, but LiveGraphics3D is not equipped to make this simplification.)
  2. A Point is the only primitive which can be moved this way. On the next two pages we'll discuss how to make other objects move.
  3. It was not strictly necessary to use the dependent variable z in this example. Replacing Point[{x,y,z}] with Point[{x,y,2*y*Exp[-x^2-y^2]}] would result in the same display, and the rule z -&gt; 2y*Exp[-x^2-y^2] would no longer be needed.
  4. As you examine examples using LiveGraphics3D on the web, it is also worth noting that it is common to combine two Ifstatements such as x -&gt; If[x &lt; -1, -1, x],  x -&gt; If[x &gt; 3, 3, x] into the more compact form x -&gt; If[x &lt; -1, -1, If[x &gt; 3, 3, x]]. This expression is also equivalent to x -&gt; Max[ -1, Min[x, 3] ].

Jonathan Rogness and Martin Kraus, "Constructing Mathlets Quickly using LiveGraphics3D - Parametrized Graphics," Convergence (May 2006)