Maya Node Math: Vector Operations

This tutorial introduces and demonstrates the following vector operations:

  • Magnitude measurement
  • Normalisation
  • The cross product
  • The dot product
  • Addition

Getting a Vector’s Magnitude (Length)

You can use a vector’s magnitude to measure distances or ratios, or to create custom scaling setups. Let’s assume you’ve already derived the vector output between two objects (transforms), as described in Vectors and How to Get Them:

cube_vect

To get an output plug for the vector’s length, follow these steps:

  1. Create a distanceBetween node.
  2. Connect your vector output (this will be output3D on the plusMinusAverage node you used to calculate the vector) into the distanceBetween’s point2 input. Leave everything else as-is.
  3. The vector magnitude is now the distanceBetween’s distance output.

Your network should look something like this (node names may differ):

vec_len

The mathematical formula for deriving a vector’s magnitude (length) can be found here.

Normalising a Vector

Normalising a vector means resetting its magnitude to 1.0. You may want to do this because you want to control its length separately (e.g. for “telescopic” effects), or because you are managing scaling or shearing within a custom transformation matrix (more on this later).

To normalise a vector, you need to divide each of its XYZ components by its magnitude. So, first derive the magnitude using the method described earlier, and then do the following:

  1. Create a multiplyDivide node, and set its operation to Divide (2).
  2. Connect your vector output into input1 on the multiplyDivide.
  3. Connect the distance output of the distanceBetween node you used to read the vector magnitude three times; once for each XYZ component of the multiplyDivide node’s input2 attribute.
  4. The multiplyDivide node’s output attribute is now your normalised vector.

As before, in the below example the vector we want to normalise is being generated by the output3D attribute on the plusMinusAverage node called “vec_AB”.

norm_vec_netw

If you want to normalise a vector that you have produced using a vectorProduct node, you can skip the above and simply set the vectorProduct’s normalizeOutput attribute to True.

Changing a Vector’s Magnitude (Length)

To change a vector’s magnitude, simply use a multiplyDivide node to multiply each of its three XYZ components by the desired factor.

Getting the Cross Product of Two Vectors

The cross product of two vectors produces a third vector which is perpendicular to both of them. The directions of the input vectors will determine which side the third vector will face.

For example, let’s assume you have three points in space, A, B and C, here represented by a cube, a cone and a sphere:

abcpoints

Say you’ve derived a vector from A to B, and another one from B to C (say, using the techniques described in Vectors and How to Get Them). The cross product AB x BC will face downwards:

dwn_cross

 

If the vectors are reversed, and the cross product is executed for CB x BA instead, the cross product will face upwards:

up_cross

Here’s one way to predict how a cross product will behave: If your vectors are forming a clockwise triangle, the cross product will face away from you. Otherwise, if the triangle is anti-clockwise, the cross product will face towards you. This is similar to how polygon normals behave. See what happens if you draw a couple of polygonal triangles, one clockwise, the other anticlockwise, and switch on Display > Polygons > Face Normals (you may have to also enter a value in Normals Size… to see them clearly):

face_norm

The cross product will also flip if you switch the order of multiplication,  i.e. if you perform BC x AB instead of AB x BC.

To get the cross product of two vectors, do the following:

  1. Create a vectorProduct node and set its operation to Cross Product.
  2. Plug your vector attributes (see Vectors and How to Get Them on how to create these)  into input1 and input2 respectively.
  3. The vectorProduct’s output attribute is now the cross product.

Here’s an example node network (inputs into the vector_AB / vector_BC nodes are omitted for brevity):

xp_tree

 

Getting The Dot Product

The dot product of two vectors is a scalar (single) value, not a vector. Its value ranges from -1.0 to 1.0, and tells you the following:

  • If the value -1.0, the two vectors are pointing in precisely opposite directions.
  • If the value is 0.0, the two vectors are precisely perpendicular to each other.
  • If the value is 1.0, the two vectors are pointing in precisely the same direction.

dot_prod

The dot product works well for driven keys. For example, you could use it to drive a deformation effect based on how closely aligned two skeletal bones are.

Follow these steps to get the dot product of two vector outputs:

  1. Create a vectorProduct node. These come with the operation attribute set to Dot Product by default.
  2. Switch on Normalize Output. This will ensure that the dot product values will be in the -1.0 to 1.0 range.
  3. Connect your vectors into the vectorProduct’s inputs.
  4. The vectorProduct’s outputX attribute is now the dot product.

As before, the example network below assumes you’ve used the plusMinusAverage technique to produce your vectors, and does not show incoming connections:

dotprod_netw

 

Adding Vectors

Wolfram Mathworld gives a concise description of vector addition:

The vector sum is obtained by placing the vectors head to tail and drawing the vector from the free tail to the free head.

So the vector sum can be visualised either as the ‘missing side’ of the triangle by two vectors:

vec_sum_across

 

In other situations, it’s more intuitive to think of it as a mid-line between the two other vectors:

vec_sum_thru

Remember that vectors have no inherent position, only direction and magnitude. In the above examples, we are only ‘positioning’ them for visualisation. The vector sum is the same in both situations.

To add two vectors, simply plug their outputs into a plusMinusAverage node and grab its output3D output:

vecsum_net