Visualizing Functions
Vector fields and vector functions arise frequently outside of electromagnetism. They are a mainstay of mathematics, science and engineering. This example visualizes a arbitrary vector valued function. Previously we implicitly defined a vector field as the electric field from configured charges. This time we explicitly define the vector field.
In addition to the vector field, we also define a list of start points. Start points are where the framework begins tracing a field line. Each start point contains x, y and z coordinates and a direction indicator. If the direction indicator is positive, the start point marks the beginning of the field line and the the field line is traced forward, along the direction of the vector, from that point. If the direction indicator is negative, the point marks the end of the field line and the field is traced backwards from that point.
This is something that immediately calls out for an improvement in the framework. Indeed, working with vector functions is the area of greatest progress right now.
The steps to visualize a vector valued function are similar to what we are familiar with from the electric field examples.
- Include the VField toolkit on your page.
- Configure the visualization.
- Define the function.
- List the start points.
- Give a place to draw the visualization.
Include VField
<script defer src="http://vizit.github.io/vfield/js/VField.min.js">
</script>
We don't setup any advanced interactions, so we don't need the Lesson toolkit.
Configure the visualization
This configures a simple vector field
, which generates a visualization
by tracing field lines and drawing vectors along those field lines. This time we
explicitly define a vector function, f
. The function definition, f
is easily modified to provide different vector components.
<script>
// This object is loaded by the VizBuilder on the DOMReady event.
var VISUALIZATION_CONFIG
= {
// This is a simple vector field, so we draw vectors
// representing the field along the field lines.
type: "simple vector field",
canvas: "vectorCanvas",
arrowSize: 0.25,
scale: 25.0,
// f is a vector valued function.
f: {
type: "function",
args: "x, y, z",
body: "var vx, vy, vz;"
+ "vx = x;"
+ "vy = -y;"
+ "vz = z;"
+ "return [vx, vy, vz];"
},
// The start points are the beginnings of the field lines.
startpoints: [
// x>0, y=10, z=0
[ 1.0, 10.0, 0.0, 1.0], [ 2.0, 10.0, 0.0, 1.0], [ 3.0, 10.0, 0.0, 1.0], [ 4.0, 10.0, 0.0, 1.0], [ 5.0, 10.0, 0.0, 1.0],
// x>0, y=-10, z=0
[ 1.0, -10.0, 0.0, 1.0], [ 2.0, -10.0, 0.0, 1.0], [ 3.0, -10.0, 0.0, 1.0], [ 4.0, -10.0, 0.0, 1.0], [ 5.0, -10.0, 0.0, 1.0],
// x<0, y=10, z=0
[-1.0, 10.0, 0.0, 1.0], [-2.0, 10.0, 0.0, 1.0], [-3.0, 10.0, 0.0, 1.0], [-4.0, 10.0, 0.0, 1.0], [-5.0, 10.0, 0.0, 1.0],
// x<0, y=-10, z=0
[-1.0, -10.0, 0.0, 1.0], [-2.0, -10.0, 0.0, 1.0], [-3.0, -10.0, 0.0, 1.0], [-4.0, -10.0, 0.0, 1.0], [-5.0, -10.0, 0.0, 1.0],
// x>0, y=10, z=1
[ 1.0, 10.0, 1.0, 1.0], [ 2.0, 10.0, 1.0, 1.0], [ 3.0, 10.0, 1.0, 1.0], [ 4.0, 10.0, 1.0, 1.0], [ 5.0, 10.0, 1.0, 1.0],
// x>0, y=-10, z=1
[ 1.0, -10.0, 1.0, 1.0], [ 2.0, -10.0, 1.0, 1.0], [ 3.0, -10.0, 1.0, 1.0], [ 4.0, -10.0, 1.0, 1.0], [ 5.0, -10.0, 1.0, 1.0],
// x<0, y=10, z=1
[-1.0, 10.0, 1.0, 1.0], [-2.0, 10.0, 1.0, 1.0], [-3.0, 10.0, 1.0, 1.0], [-4.0, 10.0, 1.0, 1.0], [-5.0, 10.0, 1.0, 1.0],
// x<0, y=-10, z=1
[-1.0, -10.0, 1.0, 1.0], [-2.0, -10.0, 1.0, 1.0], [-3.0, -10.0, 1.0, 1.0], [-4.0, -10.0, 1.0, 1.0], [-5.0, -10.0, 1.0, 1.0],
// // x>0, y=10, z=-1
[ 1.0, 10.0, -1.0, 1.0], [ 2.0, 10.0, -1.0, 1.0], [ 3.0, 10.0, -1.0, 1.0], [ 4.0, 10.0, -1.0, 1.0], [ 5.0, 10.0, -1.0, 1.0],
// x>0, y=-10, z=-1
[ 1.0, -10.0, -1.0, 1.0], [ 2.0, -10.0, -1.0, 1.0], [ 3.0, -10.0, -1.0, 1.0], [ 4.0, -10.0, -1.0, 1.0], [ 5.0, -10.0, -1.0, 1.0],
// x<0, y=10, z=-1
[-1.0, 10.0, -1.0, 1.0], [-2.0, 10.0, -1.0, 1.0], [-3.0, 10.0, -1.0, 1.0], [-4.0, 10.0, -1.0, 1.0], [-5.0, 10.0, -1.0, 1.0],
// x<0, y=-10, z=-1
[-1.0, -10.0, -1.0, 1.0], [-2.0, -10.0, -1.0, 1.0], [-3.0, -10.0, -1.0, 1.0], [-4.0, -10.0, -1.0, 1.0], [-5.0, -10.0, -1.0, 1.0]
]
}
</script>
This configuration draws onto the vectorCanvas
canvas. We set an
arrowSize
of 0.25 to scale down the size of the arrows and make a
clearer representation of the field.
This time f
is an explicit function. Contrast this
with the first example, which setup a charge
configuration.
The args
are the parameters, or arguments, passed into the function.
They are always the x, y and z coordinates, but setting the
args
provides an easy way to establish more meaningful names. For
example, we might set args
of width, height, and
length then use these more meaningful variables in the function rather than
the generic x, y and z if they match the specific problem.
The function is specified by giving the body of a JavaScript function, which returns a three element vector. The vector contains the x, y and z components of the vector.
The last piece of the configuration is the startpoints
. There are many
startpoints
so they are contained in an array [ ... ]. Each point contains
four numbers, so each point is also an array and the startpoints
are an
array of arrays.
The first start point [ 1.0, 10.0, 0.0, 1.0] contains x, y and z coordinates (1.0, 10.0, 0.0) and the direction indicator 1.0. The coordinates are where we start tracing the field line. This point generates a vector just to the right of center at the top of the graph. The positive direction indicator indicates we trace the field line along the direction of the vector.
Give a place to draw
<figure class="center">
<!--This is the canvas for our vector field visualization. -->
<canvas id="vectorCanvas" width="350" height="350"></canvas>
<figcaption>The vector field <math>
<mi mathvariant='bold'>f</mi>
<mo>=</mo> <mi>x</mi><mover><!-- i-hat --><mi mathvariant="bold">ı</mi><mo>^</mo></mover>
<mo>-</mo><mi>y</mi><mover><!-- j-hat --><mi mathvariant="bold">ȷ</mi><mo>^</mo></mover>
<mo>+</mo><mi>z</mi><mover><!-- k-hat --><mi mathvariant="bold">k</mi><mo>^</mo></mover>
</math>.
</figure>
Perhaps the most interesting point here is the use of MathML, with MathJax to provide rendering on browsers that do not support MathML yet.
This is a 350x350 canvas, slightly larger than the 300x300 used in earlier examples. The graphics automatically scale cleanly with the canvas's size with no pixelization or other artifacts. A WebGL canvas can also be scaled by setting the width or height CSS attributes. The WebGL is always rendered into the canvas's explicit height and width. That image will then be scaled according to the CSS height and width. This has the advantage of allowing you to render to a smaller image and scale it to a large presentation. The disadvantage is that the scaled image will not be as clear or clean as an unscaled image.