Vector Operations edit page

Directions are added, scaled and multiplied like ordinary numbers, and every operation works on a whole list of directions at once. That is the reason a loop over vectors is almost never needed in MTEX.

plottingConvention.default('y↑→x');

Building New Directions

Sums and multiples of the specimen axes vector3d.X, vector3d.Y and vector3d.Z are directions again.

v = vector3d.X + 2*vector3d.Y
v = vector3d (y↑→x)
  x y z
  1 2 0

+, -, *, the inner product dot and the cross product cross all behave as in linear algebra.

u = dot(v,vector3d.Y) * vector3d.Y + 2 * cross(v,vector3d.Z)
u = vector3d (y↑→x)
  x y z
  4 0 0

Angles

The angle between two directions is a central measurement in texture analysis - for example, how far a lattice-plane normal is tilted away from the sheet normal. The angle between complete crystal orientations is a different operation, introduced in the misorientation chapter.

angle(vector3d.X,vector3d.Y) ./ degree
ans =
    90

The result is in radians, hence the division by degree, and it lies between \(0\) and \(180^\circ\). If the two directions are axes rather than directions the answer is never obtuse, which is the subject of Axes and Antipodal Symmetry.

Length

norm is the length of a direction and normalize divides it out.

norm(u)
ans =
     4
u = normalize(u)
u = vector3d (y↑→x)
  x y z
  1 0 0

Normalising changes nothing about where the direction points, so it changes nothing about a spherical plot either. It matters when the numbers themselves are used, for instance because dot of two unit vectors is the cosine of the angle between them.

dot(normalize(v),vector3d.Y)
ans =
    0.8944

The Available Operations

angle(v1,v2)

angle between two directions

dot(v1,v2)

inner product

cross(v1,v2)

cross product

norm(v)

length

normalize(v)

length scaled to one

orthProj(v,N)

component orthogonal to N

perp(v)

a direction orthogonal to all of v

sum(v)

sum over the list

mean(v)

mean direction of the list

polar(v)

the two spherical angles

rotate(v,rot)

turn by a rotation

Lists of Directions

Square brackets join directions into one list, and the entries are read back by their index.

w = [v,u];
w(1)
ans = vector3d (y↑→x)
  x y z
  1 2 0

Arithmetic on a list is done entry by entry. Adding a single direction to a list of five adds it to each of them, so an operation that looks like it needs a loop usually does not.

w = w + v
w = vector3d (y↑→x)
 size: 1 × 2
  x y z
  2 4 0
  2 2 0

Lists are indexed as numeric arrays are, by position or by a logical condition. Here a file of a thousand directions is loaded and only those with a polar angle below \(60^\circ\) are kept, see Lists and Indexing.

fname = fullfile(mtexDataPath,'vector3d','vectors.txt');
v = vector3d.load(fname,'ColumnNames',{'polar angle','azimuth angle'})
v = vector3d (y↑→x)
 size: 1000 × 1
scatter(v(v.theta < 60*degree),'grid','on')

The outer ring of the projection is empty now. It held the 236 directions that lie more than \(60^\circ\) away from the Z axis.

Averaging a List

mean averages the coordinates entry by entry, so it points into the middle of the list.

mean(v)
ans = vector3d (y↑→x)
       x      y      z
  -0.137  0.198  0.677

Its length says how tightly the list is clustered: unit directions all pointing the same way average to length one, a list spread over the sphere to something much shorter - here 0.72. Directions pointing opposite ways cancel outright. For axes, where v and -v mean the same thing, that cancellation is wrong and the mean has to be taken with the 'antipodal' flag, see Axes and Antipodal Symmetry.

Next

Turning a direction into another one is the job of a rotation, and Density Estimation replaces a long list of directions by a smooth function on the sphere.