A Miller represents either a direct-lattice vector \([uvw]\) or a reciprocal-lattice normal \((hkl)\) in a crystal frame. It supports ordinary vector geometry, but comparisons have one extra input: crystal symmetry.
By default, angle, dot and eq compare a vector with the symmetry orbit of the other vector. In contrast, constructions such as cross act on the indexed vectors actually supplied. This page shows when to keep the default and when to request 'noSymmetry'.
Read Miller Indices and Lattice Metric and Plane Geometry first if direct and reciprocal indices are new. Crystal Symmetries introduces the point groups used here, while Axes and Antipodal Symmetry explains when opposite vectors represent the same axis.
plottingConvention.default('y↑→x');A Kikuchi Pattern as a Geometric Map
A simulated spherical Kikuchi pattern of quartz makes the operations visible. This is a master pattern on the sphere, not a raw planar detector image. The left plot shows the pattern, and the right plot shows its spherical Radon transform.
A band centre is a great circle on the pattern. The transform maps that great circle to the point representing its plane normal.
data = load([mtexDataPath filesep 'quartzPattern.mat']);
pattern = data.pattern;
[~,ax1] = plot(pattern,'resolution',0.25*degree,'complete','upper',...
'UVTW','noLabel');
mtexColorMap black2white
nextAxis
[~,ax2] = plot(pattern.radon,'resolution',0.25*degree,'complete','upper',...
'hkil','noLabel');
mtexColorMap black2white
The brightest bands belong to three strongly reflecting quartz forms: the hexagonal prism and the positive and negative rhombohedra. Each form is introduced below by one plane normal.
% extract the crystal symmetry
cs = pattern.CS;
m = Miller(-1,0,1,0,cs,'hkil'); % hexagonal prism
r = Miller(0,-1,1,1,cs,'hkil'); % positive rhombohedron
z = Miller(0,1,-1,1,cs,'hkil'); % negative rhombohedronDrawn in both plots, a plane is a great circle on the left and a point on the right. The matching colours identify the same plane in the two representations.
hold on
circle(m,'parent',ax1,'color','lightBlue')
circle(r,'parent',ax1,'color','red')
circle(z,'parent',ax1,'color','yellow')
opt = {'marker','s','MarkerFaceColor','none','parent',ax2,...
'labeled','backgroundColor','w','linewidth',2};
plot(m,opt{:},'markerEdgeColor','lightBlue')
plot(r,opt{:},'markerEdgeColor','red')
plot(z,opt{:},'markerEdgeColor','yellow')
Symmetrically Equivalent Planes and Directions
A symmetry orbit contains the vectors obtained by applying every operation of the crystal point group. Its members are symmetrically equivalent because the crystal cannot distinguish the corresponding settings.
The family of directions equivalent to \([uvw]\) is written \(\langle uvw\rangle\). The family of planes equivalent to \((hkl)\) is written \(\{hkl\}\). symmetrise lists the orbit as directed vectors.
symmetrise(r)ans = Miller (alpha-quartz low)
size: 6 × 1
h k i l
0 -1 1 1
0 1 -1 -1
1 0 -1 1
1 -1 0 -1
-1 1 0 1
-1 0 1 -1Quartz point group 321 has six operations, and none repeats this normal. The output therefore contains six directed normals. For this rhombohedron they form three opposite pairs.
A geometric plane is unchanged when its normal is reversed. Thus the six directed normals describe three distinct plane axes. Adding the symmetry orbits to the plots accounts for the corresponding bands.
hold on
circle(m.symmetrise,'parent',ax1,'color','lightBlue')
circle(r.symmetrise,'parent',ax1,'color','red')
circle(z.symmetrise,'parent',ax1,'color','yellow')
plot(m,opt{:},'markerEdgeColor','lightBlue','symmetrised')
plot(r,opt{:},'markerEdgeColor','red','symmetrised')
plot(z,opt{:},'markerEdgeColor','yellow','symmetrised')
The option 'symmetrised' on plot performs the same expansion. A plain symmetrise call keeps one entry per symmetry operation and may contain repeated vectors. Use 'unique' when the number of distinct members is the question.
directedNormalCount = length(symmetrise(r,'unique','noAntipodal'))directedNormalCount =
6The first count keeps opposite normals distinct. The 'antipodal' option instead treats a vector and its negative as the same axis.
planeAxisCount = length(symmetrise(r,'unique','antipodal'))planeAxisCount =
3The two outputs are 6 directed normals and 3 plane axes. Point-group equivalence and antipodal equivalence are separate choices; select the one that matches the physical object being described.
Multiplicity
The multiplicity is the number of distinct directed vectors in a symmetry orbit. It is the count returned by symmetrise(...,'unique','noAntipodal'). A direction on a symmetry axis has lower multiplicity because some operations leave it fixed.
For diffraction with Friedel equivalence, opposite reflection normals contribute together. Using a Laue group includes that equivalence in the conventional multiplicity factor for a powder reflection.
csCubic = crystalSymmetry('m-3m');
hCubic = Miller({1,0,0},{1,1,0},{1,1,1},csCubic);
multiplicity(hCubic)ans =
6
12
8The cubic \(\{100\}\), \(\{110\}\) and \(\{111\}\) forms have multiplicities 6, 12 and 8. The order of the indices does not determine this count; the stabilising symmetry of the direction does.
Are Two Normals Equivalent?
The two objects below are opposite directed normals. The operator == asks whether point group 321 maps one normal onto the other.
r1 = Miller(1,1,-2,0,cs,'hkil');
r2 = Miller(-1,-1,2,0,cs,'hkil');
r1 == r2ans =
logical
0The result is false because no operation of 321 makes that mapping. Treating the normals as axes makes their signs irrelevant.
eq(r1,r2,'antipodal')ans =
logical
1The second result is true. This distinction matters whenever directed crystal vectors, plane axes and Friedel-equivalent reflections appear in the same calculation.
Does a Direction Lie in a Plane?
A direction \([uvw]\) lies in a plane \((hkl)\) when their scalar product is zero. In three-index notation this is the zone law
\[hu+kv+lw=0.\]
Incidence concerns the two indices that were written. Use 'noSymmetry' so that dot does not substitute a symmetry-equivalent vector.
csOrtho = crystalSymmetry('mmm',[4 5 6]);
plane = Miller(1,1,0,csOrtho,'hkl');
directionInPlane = Miller(1,-1,0,csOrtho,'uvw');
dot(plane,directionInPlane,'noSymmetry')ans =
0Zero confirms that \([1\bar{1}0]\) lies in \((110)\). In contrast, the result for \([100]\) is 1, so that direction does not lie in the plane.
dot(plane,Miller(1,0,0,csOrtho,'uvw'),'noSymmetry')ans =
1This Cartesian dot-product test also works with four-index trigonal and hexagonal notation. There is no need to translate the indices manually.
Zone Axes and Spanned Planes
Two lattice planes intersect along a lattice direction called a zone axis. Its direction is the cross product of their reciprocal normals.
d1 = round(cross(m,r))
plot(d1,'marker','s','parent',ax1,'MarkerFaceColor','lightgreen',...
'labeled','backgroundColor','w')
circle(d1,'parent',ax2,'linecolor','lightgreen')d1 = Miller (alpha-quartz low)
U V T W
-1 2 -1 3
The output uses UVTW because a cross product of two reciprocal normals is a direct-lattice direction. round rescales it to small integer indices.
The green square lies where the two corresponding bands cross in the pattern. In the Radon plot, its green great circle passes through their two normal points.
d2 = Miller(-2,0,1,cs,'uvw')
plot(d2,'marker','s','parent',ax1,'MarkerFaceColor','Orange',...
'labeled','backgroundColor','w')
circle(d2,'parent',ax2,'linecolor','orange')d2 = Miller (alpha-quartz low)
u v w
-2 0 1
Conversely, two direct-lattice directions span a plane. Their cross product is displayed in reciprocal hkil notation.
n = round(cross(d1,d2))
circle(n,'parent',ax1,'linecolor','white')
plot(n,opt{:},'MarkerEdgeColor','white')n = Miller (alpha-quartz low)
h k i l
1 -2 1 2
The white band contains d1 and d2 in the pattern. In the Radon plot, the white normal lies where the green and orange great circles intersect.
Symmetry-Reduced and Geometric Angles
By default, angle returns the smallest angle between the first vector and the symmetry orbit of the second. The result is independent of which equivalent index triplet was supplied.
symmetryAngle = angle(r1,r2) / degreesymmetryAngle =
60.0000The point-group-reduced angle is \(60^\circ\). If the normals represent plane axes, include antipodal equivalence as well.
axisAngle = angle(r1,r2,'antipodal') / degreeaxisAngle =
1.2074e-06The result is numerically close to zero. To compare only the two Cartesian vectors as written, ignore crystal symmetry.
geometricAngle = angle(r1,r2,'noSymmetry') / degreegeometricAngle =
180.0000The geometric angle is \(180^\circ\) because the normals are exactly opposite. Thus the same two index sets give a \(60^\circ\) point-group angle, a near-zero plane-axis angle and a \(180^\circ\) geometric angle.
The option 'noSymmetry' is available to many commands that accept crystal directions or orientations. Use it when the indexed vectors themselves, rather than their symmetry classes, are the subject.
From the Crystal Frame into the Specimen Frame
An orientation states how a crystal is placed in the specimen. It maps a direction from the Cartesian crystal frame into the specimen frame.
ori = orientation.byEuler(10*degree,20*degree,30*degree,'Bunge',cs);
close all
plot(ori * pattern,'resolution',0.25*degree,'complete','upper')
mtexColorMap black2white
The whole pattern has moved rigidly with the crystal. Multiplying the zone axis by the same orientation returns a specimen direction rather than a Miller object.
specimenDirection = ori * d1
hold on
plot(specimenDirection,'marker','s','MarkerFaceColor','lightgreen',...
'label',char(d1,'latex'),'backgroundColor','w')
hold offspecimenDirection = vector3d (y↑→x)
x y z
-0.427 -0.0286 0.592
Applying the orientation to the full symmetry orbit marks every specimen direction in which this crystal family points.
hold on
plot(ori*d1.symmetrise,'marker','s','MarkerFaceColor','lightgreen',...
'label',char(d1,'latex'),'backgroundColor','w')
hold off
That set is the pole figure of this one orientation for the family represented by d1.
Cartesian Components Without Crystal Metadata
Casting a Miller to vector3d copies its Cartesian components but drops the crystal symmetry and crystal frame. The result is frame-free: it has an empty frame and resolves against the session default when it is rendered.
cartesianDirection = vector3d(d1)cartesianDirection = vector3d (y↑→x)
x y z
-0.246 0.426 0.541The frame name shown in the display is therefore the current session default, not a frame stored by the vector. The empty stored frame confirms that distinction.
isFrameFree = isempty(cartesianDirection.frame)isFrameFree =
logical
1The result is true. This cast is not a frame change; it removes the information needed to interpret the components as lattice indices. A true frame change re-expresses the same physical object in a named frame and leaves the object itself untouched.
The ordinary spherical coordinates remain available. Called without output arguments, polar prints the polar angle from +Z and the azimuth from +X in degrees.
polar(d1)polar angle 42.3°
azimuthal angle 120.0°References
- The International Union of Crystallography, Zone axis, defines the zone axis and the Weiss zone law used for the incidence test.
- U. Shmueli, Reciprocal space in crystallography, International Tables for Crystallography B, ch. 1.1, 2006, develops the direct and reciprocal geometry behind these operations.
- A. Looijenga-Vos and M. J. Buerger, Space-group determination and diffraction symbols, International Tables for Crystallography A, ch. 3.1, 2006, explains Friedel equivalence and Laue symmetry in diffraction.
- N. C. Krieger Lassen, D. Juul Jensen and K. Conradsen, Image Processing Procedures for Analysis of Electron Back Scattering Patterns, Scanning Microscopy 6, article 7, 1992, introduces transform-based localisation of Kikuchi bands for automated indexing.
- A. Morawiec, Orientations and Rotations: Computations in Crystallographic Textures, Springer, 2004, develops symmetry orbits and symmetry-reduced angles for texture analysis.
Next
Continue in chapter order with Reference System, which explains how the lattice basis is embedded in the Cartesian crystal frame. Fundamental Sector later selects one representative from each symmetry-equivalent direction family.
Continue with Defining Orientations to place a crystal in a specimen. Pole Figures then plots where selected crystal directions point in that specimen.
Citing this page.
This page is part of the documentation of
MTEX, a free and open
source MATLAB toolbox for analyzing and modeling crystallographic textures.
It was written by The MTEX Developers and is published at
https://mtex-toolbox.github.io/CrystalOperations.html.
If you use MTEX, or reuse text or figures from this page, in your research,
please cite
F. Bachmann, R. Hielscher, H. Schaeben: Texture Analysis with MTEX - Free and Open Source Software Toolbox, Solid State Phenomena 160 (2010), 63-68. 10.4028/www.scientific.net/SSP.160.63
BibTeX
@article{bachmann2010mtex,
author = {F. Bachmann and R. Hielscher and H. Schaeben},
title = {Texture Analysis with MTEX - Free and Open Source Software Toolbox},
journal = {Solid State Phenomena},
volume = {160},
pages = {63-68},
year = {2010},
doi = {10.4028/www.scientific.net/SSP.160.63},
url = {https://doi.org/10.4028/www.scientific.net/SSP.160.63}
}
Other papers describing specific MTEX methods are listed under Publications — please cite the one that best fits your application. The MTEX source code is licensed under the GNU General Public License v2.0; the text and figures of this documentation are licensed under CC BY 4.0, which permits reuse — including by automated systems — provided The MTEX Developers and this page are credited.