Sometimes, we obtain landmarks from specimens containing more than
one anatomical component, and the relative positions of those components
cannot be standardized a priori. In such cases, we must ‘fix’
their relative positions prior to GPA.Geomorph
has this ability through the function fixed.angle, which
implements one approach to the problem as outlined in Adams (1999)
Evol. Ecol. Res.
Note that, at present, this function may only be used for
two-dimensional landmark data. For 3D data, one could use the R-package
ShapeRotator, which generalizes Adams (1999) for 3D
articulations.
Here we provide a simple example where we have some salamander data where the angle of articulation of the jaw is variable:

Now let’s fix the articulation angle using fixed.angle.
There are several arguments of importance in this function that we will
need to specify:
fixed.angle() (Expand for more details)
\(A\): The input data which needing to beProcrustes-aligned landmark coordinates in 3D array format.
\(art.pt\) This specifies the ‘vertex’ of the angle, or which landmark is the point of articulation of the joint; in this case, landmark 1.
\(angle.pts.1\) and \(angle.pts.2\): These arguments are used to specify the terminal landmarks of each ‘ray’ of the angle; in this case, landmarks 5 and 6:
GP <- gridPar(txt.pos = 2)
links.art <- matrix(c(1,5,1,6), ncol=2, byrow=TRUE)
colnames(links.art) <- c("start", "end")
\(rot.pts\): specifies which landmarks will actually be rotated by the function. We want the mandible to move, so we list landmarks 2, 3, 4, and 5.
\(angle\): This argument allows us to specify the angle that we want our specimens to be rotated to. The default value for this will be the angle of the mean specimen (right?). Any values indicated here will be in addition to the mean angle.
jaw.fixed <- fixed.angle(gpa.rand,
art.pt=1, angle.pts.1 = 5,
angle.pts.2 = 6, rot.pts = c(2,3,4,5))
gpa.fixed <- gpagen(jaw.fixed, print.progress = FALSE)$coords
The output of fixed.angle is a 3D array of landmark
coordinates. So, let’s compare our original dataset with variable
articulation angles, to the adjusted dataset using
plotAllSpecimens:
par(mfrow=c(1,2))
plotAllSpecimens(gpa.rand, links = plethodon$links)
mtext("Jaws Random Angles")
plotAllSpecimens(gpa.fixed, links = plethodon$links)
mtext("Jaws Standardized to Common Angle")
plotRefToTarget(gpa.rand[,,1], gpa.rand[,,1],
gridPars = GP, links = links.art, label = TRUE, method = "points")

