### Vectors and Matrices

#### Vectors

In the Managing Geometric Objects tutorial we used vector objects in various ways. Most geometric objects define vector attributes and in order to manage geometric objects, you need to know something about vectors.

Vector is one of the built-in classes in Realsoft 3D, so you don't have to include a header file to get the class defined.

A vector object defines three attributes: x, y and z. It can be used for representing geometry points, direction vectors, and many other things of 3D nature.

You can create a vector by calling:

```    v = new r3Vect();
```

which creates so called null vector. All the three attributes are initialized to zero. You can initialize a vector to a desired value by calling the set() method.

```    v.set(1, 0, 0);
```

or, simply by setting the attributes using an assignment operator:

```    v.x = 1.0;
v.y = 0;
v.z = 0;
```

You may also create a vector by defining initial x, y and z values to the constructor:

```    v = new r3Vect(1, 0, 0);
```

Vector class also defines methods for vector addition and other vector operations. For example, let's imagine we have two vectors:

```    a = new r3Vect(1, 0, 0);
b = new r3Vect(0, 1, 0);
```

Then we want to perform a vector operation c = a + b. This can be accomplished as follows:

```    c = a.add(b);
```

This corresponds to the following code:

```    c.x = a.x + b.x;
c.y = a.y + b.y;
c.z = a.z + b.z;
```

Let's take another commonly needed operation like 'scalar multiplication'. For example, if you want to perform operation 'b = a * 2.0' i.e. to double the length of the vector, call:

```    b = a.mul(2.0);
```

This corresponds to the following code:

```    b.x = a.x * 2.0;
b.y = a.y * 2.0;
b.z = a.z * 2.0;
```

There are two methods for applying most vector operations: those which result in a new vector object and those which apply the operation to the vector in question. We demonstrated the former type of methods above.

If a method name starts with letter 'f', then it represents the latter form of method i.e. it applies the vector operation to the object in question rather than resulting in a new vector. If you are familiar with Realsoft 3D Software Development Kit you will find that the method names correspond to those used in the SDK.

For example, the following method:

```    a.fadd(b);
```

adds the vector 'b' to 'a'. This corresponds the code:

```    a.x = a.x + b.x;
a.y = a.y + b.y;
a.z = a.z + b.z;
```

Or, if you want to double the length of a vector, call:

```    a.fmul(2.0);
```

which corresponds to the following code:

```    a.x = a.x * 2.0;
a.y = a.y * 2.0;
a.z = a.z * 2.0;
```

One very useful vector method is called 'noise', which allows you to compute various fractal effects. The noise takes two parameters: dimensions and octaves and results in a new vector object representing the strength of the noise field.

```    b = a.noise(3, 4);
```

For a list of all methods supported by the vector class, see the reference manual/vector class.

#### Matrices

Realsoft 3D uses a very standard 4x4 matrix to define so called 'local object space' property for all geometric objects. The matrix consists of 16 floating point values (4x4).

The mathematical theory behind matrices is beyond this tutorial. However, it is possible to use the matrix class even if you do not understand the deep theory.

The matrix class is a built-in class and there are no header files that you should include.

#### Constructing Matrices

As demonstrated in the Managing Geometric Objects tutorial, a new matrix object can be created by calling:

```    m = new r3Matrix();
```

This creates a so called 'identity' matrix. Applying such a matrix to does not transform objects in any way.

You may also pass four vector parameters to the constructor:

```    origin = new r3Vect(0, 0, 0);
x = new r3Vect(1, 0, 0);
y = new r3Vect(0, 1, 0);
z = new r3Vect(0, 0, 1);
m = new r3Matrix(origin, x, y, z);
```

The parameters define a coordinate system (i.e. a space), which is an alternative (more intuitive) representation for a matrix. For example, to construct a transformation matrix which moves the object from world origin to x=1.0, y=0.5:

```    origin = new r3Vect(1.0, 0.5, 0);
x = new r3Vect(1, 0, 0);
y = new r3Vect(0, 1, 0);
z = new r3Vect(0, 0, 1);
m = new r3Matrix(origin, x, y, z);
```

Or, to construct a matrix which scales the object to twice the original size:

```    origin = new r3Vect(0, 0, 0);
x = new r3Vect(2, 0, 0);
y = new r3Vect(0, 2, 0);
z = new r3Vect(0, 0, 2);
m = new r3Matrix(origin, x, y, z);
```

A third way to construct a matrix is by passing sixteen number parameters to the constructor, specifying the initial state of the sixteen attributes of the matrix. However, this is not very convenient and rarely used.

#### Constructing Transformation Matrices

Many applications allow you to construct matrices from a number of transformation components namely translate, scale, rotate and skew.

Concatenated transformations are executed in the reversed order (first in, last out).

Let's demonstrate this by going through a couple of examples.

If you run the following code:

```    m = new r3Matrix();
m.scale(0.5, 0.5, 0.5);
primLayer.LOCKEXCLUSIVE();
primLayer.TRANSFORM(m);
primLayer.RELEASE();
```

the result is that all the selected objects shrink towards the world origin so that they end up twice as small.

However, let us imagine you want to scale the selected objects about point [0.1, 0.2, 0.0] rather than about the origin.

To do this, you first have to move the object, so that this point matches the world origin. Then you apply the scale effect and finally you move the object back to its original position. The code to accomplish this is:

```    m = new r3Matrix();
m.translate(0.1, 0.2, 0.0);
m.scale(0.5, 0.5, 0.5);
m.translate(-0.1, -0.2, 0.0);

primLayer.LOCKEXCLUSIVE();
primLayer.TRANSFORM(m);
primLayer.RELEASE();
```

Because specified transformations are executed in reversed order, the translation [-0.1, -0.2, 0] is executed first. Then the object is scaled and finally moved back to its original position. The effect is that the object seems to be scaled down towards the point [0.1, 0.2, 0].

#### Specifying transformation center in one call

The transformation methods accept more than three parameters, allowing you to specify transformation center in one call.

The above scaling effect can easily be set up, simply by calling:

```    m = new r3Matrix();
m.scale(new r3Vect(0.1, 0.2, 0), 0.5, 0.5, 0.5);
```

SIn other words, if you pass four parameters to the scale method, the first parameter is assumed to be the origin of scale. The remaining three parameters specify scaling factors in x, y and z dimensions.

Let's take another example: to construct a transformation matrix rotating the selected objects about an axis aligned to world 'x' axis and passing through the point [0, 1, 0], call:

```    m = new r3Matrix();
m.rotate(PI, new r3Vect(0, 1, 0), new r3Vect(1.0, 0.0, 0.0));
```

The first parameter specifies rotation angle in radians. The second parameter specifies the origin of rotation and the third specifies the axis of rotation.

The script 'scripts/js/myclasses/mytransform.js' shows you couple of examples of tools transforming geometric objects. You can test these tools by selecting the pull down menu 'Scripts/Toolbars/myransform.js'.