+
+ /*
+ * rotate around the Y axis for change in X
+ * (mouse movement left/right)
+ */
+ if (x != 0)
+ {
+ rotmat.rotate(x, Axis.Y);
+ }
+
+ /*
+ * apply the composite transformation to sequence points;
+ * update z min-max range (affects colour graduation), but not
+ * x or y min-max (as this would affect axis scaling)
+ */
+ float[] centre = getCentre();
+ float zMin = Float.MAX_VALUE;
+ float zMax = -Float.MAX_VALUE;
+
+ for (int i = 0; i < npoint; i++)
+ {
+ SequencePoint sp = sequencePoints.get(i);
+ sp.translate(-centre[0], -centre[1], -centre[2]);
+
+ // Now apply the rotation matrix
+ sp.coord = rotmat.vectorMultiply(sp.coord);
+
+ // Now translate back again
+ sp.translate(centre[0], centre[1], centre[2]);
+
+ zMin = Math.min(zMin, sp.coord.z);
+ zMax = Math.max(zMax, sp.coord.z);
+ }
+
+ seqMin[2] = zMin;
+ seqMax[2] = zMax;
+
+ /*
+ * rotate the x/y/z axis positions
+ */
+ for (int i = 0; i < DIMS; i++)
+ {
+ getAxisEndPoints()[i] = rotmat.vectorMultiply(getAxisEndPoints()[i]);
+ }
+ }
+
+ /**
+ * Answers the x/y/z coordinates that are midway between the maximum and
+ * minimum sequence point values
+ *
+ * @return
+ */
+ private float[] getCentre()
+ {
+ float xCentre = (seqMin[0] + seqMax[0]) / 2f;
+ float yCentre = (seqMin[1] + seqMax[1]) / 2f;
+ float zCentre = (seqMin[2] + seqMax[2]) / 2f;
+
+ return new float[] { xCentre, yCentre, zCentre };