Version 0.59.0

Vector Calculus

Being a 3D-CAD system, trCAD works mainly on 3-dimensional space ℝ3. Therefore it contains a wide set of operations for calculating in 3-dimensional vector space. This includes

Some basic knowledge of vector calculus may be helpful in understanding this section. For reader without this, we recommend to read only the section about coordinate space and the first part about vectors that describes the vector notation used in trCAD. The sections about vector operators and matrices are not required for the next chapters.

Coordinate Space

trCAD works on a 3-dimensional, right-handed coordinate system of neutral units. The three axis directions are labeled as X, Y and Z (in this order). By default, the Z direction is meant to point upwards, while the X and Y directions extend horizontally. The origin is the point with the coordinate values ( 0.0, 0.0, 0.0 ).

The vector Data Type

In trCAD, a vector is the coordinate representation of a point in the 3d construction space. It is defined by three floating point values that are the coordinates in X, Y and Z directions. A common way to imagine a vector is an "arrow" pointing from the origin to the respective point. If a vector is used to describe the difference between two space points, the arrow is imagined to point from one of the two points to the other.

(More information about 3d vector space: https://en.wikipedia.org/wiki/Euclidean_vector .)

A pure vector value can be written by either the vector object constructor or by using the trCAD vector bracket notation:

Example

vector( 1.0, 1.0, 0.0 )    // Vector value written as vector object constructor
<[ 1.0, 1.0, 0.0 ]>        // Vector value written by vector bracket notation

Note

The vector bracket notation <[ X, Y, Z ]> can be used to define vector values.

A vector variable can thus be defined in multiple ways: by using the constructor or by copying of a vector value. Thus the three following definitions are identical:

Example

vector v1( 1.0, 1.0, 0.0 )
vector v2 = vector( 1.0, 1.0, 0.0 )
vector v3 = <[ 1.0, 1.0, 0.0 ]>

The Z coordinate can also be omitted in the vector definition. It will then automatically be set to zero. This is useful for working in a 2-dimensional environment:

Example

vector v = <[ 1.0, 2.0 ]>
echo( v )

Output

<[1,2,0]>

The different coordinate values of a vector variable can be accessed by the vector methods x, y and z in the following way:

Example

vector v( 1.0, 1.0, 0.0 )
echo( v.x + " " + v.y + " " + v.z )

Output

1 1 0

Vector Operators

Several additional operators are available to work with vector values. The first to be mentioned are the vector addition and vector subtraction operators

+ -
+= -=

They work like their default arithmetic operators counterpart but work on vectors. They return a vector that is the component-by-component sum or difference of two vectors:

Example

vector v1 = <[ 1.0, 0.0, 0.0 ]> + <[ 0.0, 2.0, 1.0 ]>
echo( v1 )
v1 -= <[ 1.0, 0.0, 0.0 ]>
echo( v1 )

Output

<[1,2,1]>
<[0,2,1]>

Similar but with a slight difference are the multiplication and division with and by a scalar. (A scalar is simply a floating point number. It is called like this to distinguish it from other objects as vectors or matrices.) They are

* /
*= /=

For the two operators in the upper line, one of the operands must be a vector and the other a scalar. For the division, the counter must be a vector and the denominator a scalar. The operators in the lower line work equally but the multiplication/division is directly applied to the left hand of the operator. The return value of all of these operations is the vector with each component multiplied/divided by the scalar value:

Example

vector v1 = <[ 1.0, 0.0, 2.0 ]> * 2.0
vector v2 = 2.0 * <[ 1.0, 0.0, 2.0 ]>
vector v3 = <[ 1.0, 0.0, 2.0 ]> / 2.0
// vector v4 = 2.0 / <[ 1.0, 0.0, 2.0 ]> // This is not allowed: the vector cannot be the denominator.
echo( v1 + "; " + v2 + "; " + v3 + ";" )

v1 *= 3.0
v2 /= 1.0
echo( v1 + "; " + v2 + ";" )

Output

<[2,0,4]>; <[2,0,4]>; <[0.5,0,1]>;
<[6,0,12]>; <[2,0,4]>;

The norm operator returns the norm of a vector, what corresponds to the length of the imagined arrow. Its operator sign is two pipe characters '|' that embrace the vector value:

| v |

Example

vector v = <[ 1.0, 2.0, -1.5 ]>
echo( "The norm of vector " + v + " is " + |v| );

Output

The norm of vector <[1,2,-1.5]> is 2.6925824

Sometimes we may want to normalize a vector, i.e. making it have a length of one. Unless the norm is not zero, we can get a normalized version of the vector by dividing by its norm:

Example

vector v = <[ 1.0, 2.0, -1.5 ]>
v /= |v|
echo( "The norm of the normalized vector v is " + |v| );

Output

The norm of the normalized vector v is 1

The scalar product (or dot product) is a second type of multiplication operation for vectors. Unlike the multiplication of a vector by a scalar that results in a vector that was described above, the scalar product is a multiplication of two vectors that results in a scalar. The scalar product uses the same operator sign:

*

but with one vector on each side:

Example

float d = <[ 1.0, 2.0, 0.0 ]> * <[ 2.0, 1.0, -1.0 ]>
echo( d )

Output

4

For more information about the scalar product see https://en.wikipedia.org/wiki/Dot_product .

A third type of multiplication that involves vector values is the vector product or cross product:

<*>

It is a multiplcation of two vectors that results in a third one with a direction perpendicular to the first two:

Example

vector v = <[ 1.0, 2.0, 0.0 ]> <*> <[ 2.0, 1.0, -1.0 ]>
echo( v )

Output

<[-2,1,-3]>

More information about the vector product see https://en.wikipedia.org/wiki/Cross_product .

The matrix Data Type

A matrix is the numerical presentation of a linear operator that can be applied to vectors in order to transform these (see https://en.wikipedia.org/wiki/Transformation_matrix ). In trCAD, matrices can be used as 3x3 matrices (classical transformation matrix), as 3x4 matrices (affine transformation including translations) or as 4x4 matrices (required for certain special numerical operations such as singular value decomposition). The definition for matrices resembles the one for vectors:

Example

// Defining of a 3x3 matrix (spaces and linebreaks used for a clearer code structure):
matrix m1 = <[<[ 0.5,  0.0, -0.5 ]>,
              <[ 0.0,  1.0,  0.0 ]>,
              <[ 2.0,  0.0,  0.5 ]>]>
echo( m1 )

Output

<[<[0.5,0,-0.5]>,<[0,1,0]>,<[2,0,0.5]>]>

In addition a 3x3 matrix can be written in a reduced 2x2 form, defining the upper left part of the matrix only. The not defined entries of the matrix are set to zero implicitly:

Example

// Defining of a 2x2 subgrid of a 3x3 matrix:
matrix m2 = <[<[ 0.5, -0.5 ]>,
              <[ 2.0,  0.5 ]>]>
echo( m2 )

Output

<[<[0.5,-0.5,0]>,<[2,0.5,0]>,<[0,0,0]>]>

A 3x4 matrices has one additional column that is used to store a translation vector. This allows to include translations into the matrix form. The definition has the following form:

Example

// Defining of a 3x4 matrix with a translational vector <[1,2,1]>:
matrix m3 = <[<[ 0.5,  0.0, -0.5, 1.0 ]>,
              <[ 0.0,  1.0,  0.0, 2.0 ]>,
              <[ 2.0,  0.0,  0.5, 1.0 ]>]>
echo( m3 )

Output

<[<[0.5,0,-0.5,1]>,<[0,1,0,2]>,<[2,0,0.5,1]>]>

In the same way, a 4x4 matrix can be defined:

Example

// Defining of a 4x4 matrix:
matrix m4 = <[<[ 0.5,  0.0, -0.5, 1.0 ]>,
              <[ 0.0,  1.0,  0.0, 2.0 ]>,
              <[ 2.0,  0.0,  0.5, 1.0 ]>,
              <[ 0.5,  1.5,  0.0, 2.0 ]>]>
echo( m4 )

Output

<[<[0.5,0,-0.5,1]>,<[0,1,0,2]>,<[2,0,0.5,1]>,<[0.5,1.5,0,2]>]>

Matrix Operators

For calculations with matrices there are three types of operations for the three data types a matrix can intract with: matrix-scalar interaction, matrix-vector interaction and matrix-matrix interaction.

Matrix-Scalar Interaction

The simplest case of matrix operations is the matrix-scalar multiplication where a matrix is multiplied by a scalar value (i.e. a floating point number). Each component of the matrix is multiplied by the scalar separately. For this the matrix-scalar product operators are used:

* *=

In the following example, the matrix m1 is multiplied by scalar value 2.0, first using the '*' operator and then using the '*=' operator:

Example

matrix m1 = <[<[ 0.5,  0.0, -0.5 ]>,
              <[ 0.0,  1.0,  0.0 ]>,
              <[ 2.0,  0.0,  0.5 ]>]>
matrix m2 = 2.0 * m1
echo( m2 )

m1 *= 2.0
echo( m1 )

Output

<[<[1,0,-1]>,<[0,2,0]>,<[4,0,1]>]>
<[<[1,0,-1]>,<[0,2,0]>,<[4,0,1]>]>

The matrix-scalar division operators

/ /=

work in analogy to the matrix-scalar product, each component of the matrix is devided by the scalar value:

Example

matrix m1 = <[<[ 0.5,  0.0, -0.5 ]>,
              <[ 0.0,  1.0,  0.0 ]>,
              <[ 2.0,  0.0,  0.5 ]>]>
echo( m1 / 2.0 )

Output

<[<[0.25,0,-0.25]>,<[0,0.5,0]>,<[1,0,0.25]>]>

All matrix-scalar operations work on 3x4 and 4x4 matrices the same way as on 3x3 matrices.

Matrix-Vector Interaction

A matrix is multiplied by a vector v1 using the matrix-vector product operator.

*

The operation returns another vector v2 that is the result of the application of the matrix transformation to v1:

Example

matrix m1 = <[<[ 0.5,  0.0, -0.5 ]>,
              <[ 0.0,  1.0,  0.0 ]>,
              <[ 2.0,  0.0,  0.5 ]>]>
vector v1 = <[ 0.0, 1.0, 1.0 ]>
vector v2 = m1 * v1
echo( v2 )

Output

<[-0.5,1,0.5]>

Note

Since only a matrix can be applied to a vector, not a vector to a matrix, the form v1 * m1, where v1 would need to be a transposed vector, is not supported. Therefore there is as well no operator '*=' for the matrix-vector product, which would imply evaluating v1 * m1.

Matrix-Matrix Interaction

The matrix-matrix multiplication operators

* *=

are used for multiplying m1 by another matrix m2 (see https://en.wikipedia.org/wiki/Matrix_multiplication ). If the resulting matrix m3 = m1 * m2 is later applied to a vector, this corresponds to a sequential application of the two matrices, first of m2 and then of m1. So in the sequence m1 * m2 * v1 the matrix m1 is applied to m2 * v1. Therefore it is as well said, that m1 is applied to m2.

Example

matrix m1 = <[<[ 0.5,  0.0, -0.5 ]>,
              <[ 0.0,  1.0,  0.0 ]>,
              <[ 2.0,  0.0,  0.5 ]>]>
matrix m2 = <[<[ 3.0,  2.0, 0.5 ]>,
              <[ 2.0,  1.0, 0.0 ]>,
              <[ 0.5,  0.0, 0.0 ]>]>

vector v1 = <[ 0.0, 1.0, 2.0 ]>

 // Appliying m1 to m2 by multiplying to gain m3
matrix m3 = m1 * m2

// Appliying matrices separately
vector v2 = m2 * v1
echo( v2 )
vector v3 = m1 * v2
echo( v3 )

// Appliying multiplied matrix at once
vector v4 = m3 * v1
echo( v4 )

Output

<[3,1,0]>
<[1.5,1,6]>
<[1.5,1,6]>

Note

3x4 matrices are implicitly extended to 4x4 matrices in operations by adding a fourth row <[ 0.0, 0.0, 0.0, 1.0 ]>.

Note

In a matrix-matrix multiplication the order of the matrices matters. This means, it makes a difference, if m1 is applied to m2 * v1 or m2 is applied to m1 * v1. Speaking in mathematical term, they do not commute. That means that building the matrix-matrix product m1 * m2 yields a different result than m2 * m1. Therefore it is as well important to note that m1 *= m2 is equivalent m1 = m1 * m2:

Example

matrix m1 = <[<[ 0.5,  0.0, -0.5 ]>,
              <[ 0.0,  1.0,  0.0 ]>,
              <[ 2.0,  0.0,  0.5 ]>]>
matrix m2 = <[<[ 3.0,  2.0, 0.5 ]>,
              <[ 2.0,  1.0, 0.0 ]>,
              <[ 0.5,  0.0, 0.0 ]>]>
echo( m2 * m1 )
echo( m1 * m2 )

// Is equivalent to m1 = m1 * m2
m1 *= m2
echo( m1 )

Output

<[<[2.5,2,-1.25]>,<[1,1,-1]>,<[0.25,0,-0.25]>]>
<[<[1.25,1,0.25]>,<[2,1,0]>,<[6.25,4,1]>]>
<[<[1.25,1,0.25]>,<[2,1,0]>,<[6.25,4,1]>]>

Matrix Functions

Certain predefined functions exist that provide useful operations on matrices. These are

Matrix Inversion

Matrix inversion is provided by the inv() function. This function takes one matrix as argument and returns the inverted matrix as a result:

Example

matrix m1 = <[<[ 0.5,  0.0, -0.5 ]>,
              <[ 0.0,  1.0,  0.0 ]>,
              <[ 2.0,  0.0,  0.5 ]>]>
echo( inv( m1 ) )

echo ( inv(m1) * m1)

Output

<[<[0.4,0,0.4]>,<[0,1,0]>,<[-1.6,-0,0.4]>]>
<[<[1,0,0]>,<[0,1,0]>,<[0,0,1]>]>

Note

On inverting a 3x4 matrix, this matrix is implicitly extended to a 4x4 matrix by adding a fourth row <[ 0.0, 0.0, 0.0, 1.0 ]>. This ensures that the result of the inversion of a 3x4 matrix is another 3x4 matrix representing the reversed transformation including the correct translational part.

Example

matrix m1 = <[<[ 2.0, 0.0, 0.0, 1.0 ]>,
              <[ 0.0, 2.0, 0.0, 0.0 ]>,
              <[ 0.0, 0.0, 2.0, 0.0 ]>]>
echo( inv( m1 ) )

echo ( inv(m1) * m1)

Output

<[<[0.5,0,0,-0.5]>,<[0,0.5,0,-0]>,<[0,0,0.5,-0]>]>
<[<[1,0,0]>,<[0,1,0]>,<[0,0,1]>]>

Note

Since inverting a matrix is a operation including several numerical operations on floating point numbers the result is only accurate within the general floating point accuracy of 10E-16. This means, that inv(m1) * m1 is deviating from the identity matrix within this order of value.

🗙

Search results for