/**
   * Generates a simple MultipleAlignment: 3 structures with the same Atoms but incorreclty aligned
   * (offset of 1 position) without gaps.
   *
   * @return MultipleAlignment simple MSTA
   * @throws StructureException
   */
  private MultipleAlignment simpleMSTA() throws StructureException {

    // Generate three identical Atom arrays
    List<Atom[]> atomArrays = new ArrayList<Atom[]>(52);
    for (int i = 0; i < 3; i++) atomArrays.add(makeDummyCA(52));

    // Generate the incorrect alignment (0-1-2,1-2-3,etc)
    List<List<Integer>> alnRes = new ArrayList<List<Integer>>(3);
    for (int str = 0; str < 3; str++) {
      List<Integer> chain = new ArrayList<Integer>(50);
      for (int res = 0; res < 50; res++) chain.add(res + str);
      alnRes.add(chain);
    }

    // MultipleAlignment generation
    MultipleAlignment msa = new MultipleAlignmentImpl();
    msa.getEnsemble().setAtomArrays(atomArrays);
    BlockSet bs = new BlockSetImpl(msa);
    Block b = new BlockImpl(bs);
    b.setAlignRes(alnRes);

    // We want the identity transfromations to maintain the missalignment
    Matrix4d ident = new Matrix4d();
    ident.setIdentity();
    msa.setTransformations(Arrays.asList(ident, ident, ident));

    return msa;
  }
  public Point3d calcCenterOfRotation() {
    List<Integer> line = getLongestLayerLine();

    // can't determine center of rotation if there are only 2 points
    // TODO does this ever happen??
    if (line.size() < 3) {
      return subunits.getCentroid();
    }

    Point3d centerOfRotation = new Point3d();
    List<Point3d> centers = subunits.getOriginalCenters();

    // calculate helix mid points for each set of 3 adjacent subunits
    for (int i = 0; i < line.size() - 2; i++) {
      Point3d p1 = new Point3d(centers.get(line.get(i)));
      Point3d p2 = new Point3d(centers.get(line.get(i + 1)));
      Point3d p3 = new Point3d(centers.get(line.get(i + 2)));
      transformationMatrix.transform(p1);
      transformationMatrix.transform(p2);
      transformationMatrix.transform(p3);
      centerOfRotation.add(getMidPoint(p1, p2, p3));
    }

    // average over all midpoints to find best center of rotation
    centerOfRotation.scale(1 / (line.size() - 2));
    // since helix is aligned along the y-axis, with an origin at y = 0, place the center of
    // rotation there
    centerOfRotation.y = 0;
    // transform center of rotation to the original coordinate frame
    reverseTransformationMatrix.transform(centerOfRotation);
    //		System.out.println("center of rotation: " + centerOfRotation);
    return centerOfRotation;
  }
  /**
   * Generates a simple MultipleAlignment: 3 structures with the same Atoms but incorreclty aligned
   * with gaps.
   *
   * @return MultipleAlignment gapped MSTA
   * @throws StructureException
   */
  private MultipleAlignment gappedMSTA() throws StructureException {

    // Generate three identical Atom arrays
    List<Atom[]> atomArrays = new ArrayList<Atom[]>(30);
    for (int i = 0; i < 3; i++) atomArrays.add(makeDummyCA(30));

    // Generate alignment with nulls and some missalignments
    List<List<Integer>> alnRes = new ArrayList<List<Integer>>(3);
    List<Integer> chain1 = Arrays.asList(1, 2, 3, 5, 8, 10, 12, 15, 17, 19, 22, null, 24, 27);
    List<Integer> chain2 = Arrays.asList(1, null, 3, 6, 9, 11, 12, 15, null, 18, 22, 24, 26, 28);
    List<Integer> chain3 = Arrays.asList(1, 2, 4, 7, 9, 10, null, 15, null, 17, 22, 24, 26, 28);

    alnRes.add(chain1);
    alnRes.add(chain2);
    alnRes.add(chain3);

    // MultipleAlignment generation
    MultipleAlignment msa = new MultipleAlignmentImpl();
    msa.getEnsemble().setAtomArrays(atomArrays);
    BlockSet bs = new BlockSetImpl(msa);
    Block b = new BlockImpl(bs);
    b.setAlignRes(alnRes);

    // We want the identity transfromations to mantain the missalignments
    Matrix4d ident = new Matrix4d();
    ident.setIdentity();
    msa.setTransformations(Arrays.asList(ident, ident, ident));

    return msa;
  }
 private Matrix4d reorientHelix(int index) {
   Matrix4d matrix = new Matrix4d();
   matrix.setIdentity();
   matrix.setRotation(new AxisAngle4d(1, 0, 0, Math.PI / 2 * (index + 1)));
   matrix.mul(transformationMatrix);
   return matrix;
 }
 private static Matrix4d flipZ() {
   Matrix4d rot = new Matrix4d();
   rot.m00 = -1;
   rot.m11 = -1;
   rot.m22 = 1;
   rot.m33 = 1;
   return rot;
 }
  /* (non-Javadoc)
   * @see org.biojava.nbio.structure.quaternary.core.AxisAligner#getGeometicCenterTransformation()
   */
  @Override
  public Matrix4d getGeometicCenterTransformation() {
    run();

    Matrix4d geometricCentered = new Matrix4d(reverseTransformationMatrix);
    geometricCentered.setTranslation(new Vector3d(getGeometricCenter()));

    return geometricCentered;
  }
  /*
   * Modifies the rotation part of the transformation axis for
   * a Cn symmetric complex, so that the narrower end faces the
   * viewer, and the wider end faces away from the viewer. Example: 3LSV
   */
  private void calcZDirection() {
    calcBoundaries();

    // if the longer part of the structure faces towards the back (-z direction),
    // rotate around y-axis so the longer part faces the viewer (+z direction)
    if (Math.abs(minBoundary.z) > Math.abs(maxBoundary.z)) {
      Matrix4d rot = flipY();
      rot.mul(transformationMatrix);
      transformationMatrix.set(rot);
    }
  }
  /**
   * Calculates the min and max boundaries of the structure after it has been transformed into its
   * canonical orientation.
   */
  private void calcBoundaries() {
    minBoundary.x = Double.MAX_VALUE;
    maxBoundary.x = Double.MIN_VALUE;
    minBoundary.y = Double.MAX_VALUE;
    maxBoundary.x = Double.MIN_VALUE;
    minBoundary.z = Double.MAX_VALUE;
    maxBoundary.z = Double.MIN_VALUE;
    xzRadiusMax = Double.MIN_VALUE;

    Point3d probe = new Point3d();

    for (Point3d[] list : subunits.getTraces()) {
      for (Point3d p : list) {
        probe.set(p);
        transformationMatrix.transform(probe);

        minBoundary.x = Math.min(minBoundary.x, probe.x);
        maxBoundary.x = Math.max(maxBoundary.x, probe.x);
        minBoundary.y = Math.min(minBoundary.y, probe.y);
        maxBoundary.y = Math.max(maxBoundary.y, probe.y);
        minBoundary.z = Math.min(minBoundary.z, probe.z);
        maxBoundary.z = Math.max(maxBoundary.z, probe.z);
        xzRadiusMax = Math.max(xzRadiusMax, Math.sqrt(probe.x * probe.x + probe.z * probe.z));
      }
    }
    //		System.out.println("MinBoundary: " + minBoundary);
    //		System.out.println("MaxBoundary: " + maxBoundary);
    //		System.out.println("zxRadius: " + xzRadiusMax);
  }
 /* (non-Javadoc)
  * @see org.biojava.nbio.structure.quaternary.core.AxisAligner#getRotationMatrix()
  */
 @Override
 public Matrix3d getRotationMatrix() {
   run();
   Matrix3d m = new Matrix3d();
   transformationMatrix.getRotationScale(m);
   return m;
 }
Example #10
0
 private Point3d[] transformPoints(final Matrix4d X, final Point3d[] pnts) {
   final Point3d[] newpnts = new Point3d[pnts.length];
   for (int i = 0; i < newpnts.length; i++) {
     newpnts[i] = new Point3d(pnts[i]);
     X.transform(newpnts[i]);
   }
   return newpnts;
 }
Example #11
0
  public static void transformMesh(final TopLoc_Location loc, double[] src, float[] dst) {
    double[] matrix = new double[16];
    loc.transformation().getValues(matrix);

    Matrix4d m4d = new Matrix4d(matrix);
    Point3d p3d = new Point3d();

    for (int i = 0; i < src.length; i += 3) {
      p3d.x = src[i + 0];
      p3d.y = src[i + 1];
      p3d.z = src[i + 2];
      m4d.transform(p3d);
      dst[i + 0] = (float) p3d.x;
      dst[i + 1] = (float) p3d.y;
      dst[i + 2] = (float) p3d.z;
    }
  }
 private static void writeMatrix(Matrix4d matrix, JsonGenerator jg) {
   jg.writeStartArray("matrix");
   for (int i = 0; i < 4; i++) {
     for (int j = 0; j < 4; j++) {
       jg.write(matrix.getElement(i, j));
     }
   }
   jg.writeEnd();
 }
Example #13
0
 public Matrix44 calculateTransformation(javax.vecmath.Matrix4d m, ReferenceFrame asSeenBy) {
   ReferenceFrame vehicle = (ReferenceFrame) getParent();
   if (asSeenBy == null) {
     asSeenBy = vehicle;
   }
   if (asSeenBy == vehicle) {
     return new Matrix44(m);
   } else {
     javax.vecmath.Matrix4d vehicleInverse;
     if (vehicle != null) {
       vehicleInverse = vehicle.getInverseAbsoluteTransformation();
     } else {
       vehicleInverse = new javax.vecmath.Matrix4d();
       vehicleInverse.setIdentity();
     }
     return Matrix44.multiply(
         m, Matrix44.multiply(asSeenBy.getAbsoluteTransformation(), vehicleInverse));
   }
 }
Example #14
0
  public static void main(String[] args) {
    double[] vertexCoords = {
      1.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0
    };

    int[][] faceIndices = {{0, 3, 2, 1}, {4, 0, 1}, {4, 1, 2}, {4, 2, 3}, {4, 3, 0}};

    ConvexPolyhedron poly = new ConvexPolyhedron(vertexCoords, faceIndices);

    PolyTree pyramid = new PolyTree("pyramid", poly);
    PolyTree hourglass = new PolyTree("hourglass");

    Matrix4d X = new Matrix4d();
    X.setIdentity();
    X.setTranslation(new Vector3d(0, 0, -1));
    hourglass.addComponent("bottom", pyramid, X);

    X.setTranslation(new Vector3d(0, 0, 1));
    X.setRotation(new AxisAngle4d(1, 0, 0, Math.PI));
    hourglass.addComponent("top", pyramid, X);

    hourglass.buildBoundingHull(PolyTree.OBB_HULL);
  }
  private void calcTransformationBySymmetryAxes() {
    Vector3d[] axisVectors = new Vector3d[2];
    axisVectors[0] = new Vector3d(principalRotationVector);
    axisVectors[1] = new Vector3d(referenceVector);

    //  y,z axis centered at the centroid of the subunits
    Vector3d[] referenceVectors = new Vector3d[2];
    referenceVectors[0] = new Vector3d(Z_AXIS);
    referenceVectors[1] = new Vector3d(Y_AXIS);

    transformationMatrix = alignAxes(axisVectors, referenceVectors);

    // combine with translation
    Matrix4d combined = new Matrix4d();
    combined.setIdentity();
    Vector3d trans = new Vector3d(subunits.getCentroid());
    trans.negate();
    combined.setTranslation(trans);
    transformationMatrix.mul(combined);

    // for helical geometry, set a canonical view for the Z direction
    calcZDirection();
  }
Example #16
0
 @Override
 public javax.vecmath.Matrix4d getInverseAbsoluteTransformation() {
   synchronized (m_absoluteTransformationLock) {
     if (m_inverseAbsoluteTransformation == null) {
       m_inverseAbsoluteTransformation = getAbsoluteTransformation();
       try {
         m_inverseAbsoluteTransformation.invert();
       } catch (javax.vecmath.SingularMatrixException sme) {
         System.err.println("cannot invert: " + m_inverseAbsoluteTransformation);
         throw sme;
       }
     }
     return new javax.vecmath.Matrix4d(m_inverseAbsoluteTransformation);
   }
 }
  private double[] getSubunitZDepth() {
    int n = subunits.getSubunitCount();
    double[] depth = new double[n];
    Point3d probe = new Point3d();

    // transform subunit centers into z-aligned position and calculate
    // z-coordinates (depth) along the z-axis.
    for (int i = 0; i < n; i++) {
      Point3d p = subunits.getCenters().get(i);
      probe.set(p);
      transformationMatrix.transform(probe);
      depth[i] = probe.z;
    }
    return depth;
  }
  /* (non-Javadoc)
   * @see org.biojava.nbio.structure.quaternary.core.AxisAligner#getGeometricCenter()
   */
  @Override
  public Point3d getGeometricCenter() {
    run();

    Point3d geometricCenter = new Point3d();
    Vector3d translation = new Vector3d();
    //		reverseTransformationMatrix.get(translation);

    // TODO does this apply to the helic case?
    // calculate adjustment around z-axis and transform adjustment to
    //  original coordinate frame with the reverse transformation

    //		Vector3d corr = new Vector3d(0,minBoundary.y+getDimension().y, 0);
    //		reverseTransformationMatrix.transform(corr);
    //		geometricCenter.set(corr);

    reverseTransformationMatrix.transform(translation);
    geometricCenter.add(translation);
    return geometricCenter;
  }
Example #19
0
    @Override
    public void prologue(double t) {

      beginEqualsEnd = false;
      done = false;

      subject = WalkToAnimation.this.subject.getTransformableValue();
      m_asSeenBy = asSeenBy.getReferenceFrameValue();

      edu.cmu.cs.stage3.math.Matrix44 asSeenByTrans =
          m_asSeenBy.getTransformation(subject.getWorld());
      ((edu.cmu.cs.stage3.alice.core.Transformable) m_asSeenBy).standUpRightNow(subject.getWorld());

      m_transformationBegin = subject.getTransformation(m_asSeenBy);

      if (m_asSeenBy == null) {
        throw new edu.cmu.cs.stage3.alice.core.SimulationPropertyException(
            subject.name.getStringValue() + " needs something or someone to walk to.",
            null,
            asSeenBy);
      }
      if (subject == m_asSeenBy) {
        throw new edu.cmu.cs.stage3.alice.core.SimulationPropertyException(
            subject.name.getStringValue() + " can't walk to " + subject.name.getStringValue() + ".",
            getCurrentStack(),
            asSeenBy);
      }

      if (subject.isAncestorOf(m_asSeenBy)) {
        throw new edu.cmu.cs.stage3.alice.core.SimulationPropertyException(
            subject.name.getStringValue() + " can't walk to a part of itself",
            getCurrentStack(),
            asSeenBy);
      }

      // find end transformation
      javax.vecmath.Vector3d posAbs = getPositionEnd();
      javax.vecmath.Vector3d curPos = subject.getPosition();
      subject.setPositionRightNow(posAbs, m_asSeenBy);

      // javax.vecmath.Matrix3d paMatrix =
      // subject.calculatePointAt(m_asSeenBy, null, new
      // javax.vecmath.Vector3d(0,1,0), null, true);
      javax.vecmath.Matrix3d paMatrix =
          subject.calculatePointAt(
              m_asSeenBy, null, new javax.vecmath.Vector3d(0, 1, 0), m_asSeenBy, true);
      subject.setPositionRightNow(curPos);

      javax.vecmath.Matrix4d pov = asSeenBy.getReferenceFrameValue().getPointOfView();
      pov.set(paMatrix);
      pov.setRow(3, posAbs.x, posAbs.y, posAbs.z, 1.0);

      m_transformationEnd = new edu.cmu.cs.stage3.math.Matrix44(pov);

      double dx = m_transformationBegin.m30 - m_transformationEnd.m30;
      double dy = m_transformationBegin.m31 - m_transformationEnd.m31;
      double dz = m_transformationBegin.m32 - m_transformationEnd.m32;
      double distance = Math.sqrt(dx * dx + dy * dy + dz * dz);
      double s = distance;

      m_xHermite =
          new edu.cmu.cs.stage3.math.HermiteCubic(
              m_transformationBegin.m30,
              m_transformationEnd.m30,
              m_transformationBegin.m20 * s,
              m_transformationEnd.m20 * s);
      m_yHermite =
          new edu.cmu.cs.stage3.math.HermiteCubic(
              m_transformationBegin.m31,
              m_transformationEnd.m31,
              m_transformationBegin.m21 * s,
              m_transformationEnd.m21 * s);
      m_zHermite =
          new edu.cmu.cs.stage3.math.HermiteCubic(
              m_transformationBegin.m32,
              m_transformationEnd.m32,
              m_transformationBegin.m22 * s,
              m_transformationEnd.m22 * s);

      super.prologue(t);
      getActualStepLength();

      ((edu.cmu.cs.stage3.alice.core.Transformable) m_asSeenBy)
          .setTransformationRightNow(asSeenByTrans, subject.getWorld());
    }
Example #20
0
 public Transformable() {
   m_localTransformation = new javax.vecmath.Matrix4d();
   m_localTransformation.setIdentity();
 }
Example #21
0
  private static Element matrix4d2Transform(Matrix4d matrix4d) {
    Element transform = new BaseElement("Transform");

    Element m0 = new BaseElement("m0");
    m0.addText(
        matrix4d.getM00()
            + " "
            + matrix4d.getM01()
            + " "
            + matrix4d.getM02()
            + " "
            + matrix4d.getM03()
            + ".");
    transform.add(m0);

    Element m1 = new BaseElement("m1");
    m1.addText(
        matrix4d.getM10()
            + " "
            + matrix4d.getM11()
            + " "
            + matrix4d.getM12()
            + " "
            + matrix4d.getM13()
            + ".");
    transform.add(m1);

    Element m2 = new BaseElement("m2");
    m2.addText(
        matrix4d.getM20()
            + " "
            + matrix4d.getM21()
            + " "
            + matrix4d.getM22()
            + " "
            + matrix4d.getM23()
            + ".");
    transform.add(m2);

    Element m3 = new BaseElement("m3");
    m3.addText(
        matrix4d.getM30()
            + " "
            + matrix4d.getM31()
            + " "
            + matrix4d.getM32()
            + " "
            + matrix4d.getM33()
            + ".");
    transform.add(m3);

    return transform;
  }
  private static Matrix4d combineTransformation(
      Matrix4d matrix, Vector3d translation, Vector3d rotation) {
    Matrix4d gM = new Matrix4d(matrix);
    Matrix4d m = new Matrix4d();

    m.setIdentity();
    m.setTranslation(translation);
    gM.mul(m);

    m.setIdentity();
    m.rotZ(rotation.z);
    gM.mul(m);

    m.setIdentity();
    m.rotY(rotation.y);
    gM.mul(m);

    m.setIdentity();
    m.rotX(rotation.x);
    gM.mul(m);

    return gM;
  }
  /**
   * Computes the new transform for this interpolator for a given alpha value.
   *
   * @param alphaValue alpha value between 0.0 and 1.0
   * @param transform object that receives the computed transform for the specified alpha value
   * @since Java 3D 1.3
   */
  public void computeTransform(float alphaValue, Transform3D transform) {
    // compute the current value of u from alpha and the
    // determine lower and upper knot points
    computePathInterpolation(alphaValue);

    // Determine the segment within which we will be interpolating
    currentSegmentIndex = this.lowerKnot - 1;

    // if we are at the start of the curve
    if (currentSegmentIndex == 0 && currentU == 0f) {
      iHeading = keyFrames[1].heading;
      iPitch = keyFrames[1].pitch;
      iBank = keyFrames[1].bank;
      iPos.set(keyFrames[1].position);
      iScale.set(keyFrames[1].scale);

      // if we are at the end of the curve
    } else if (currentSegmentIndex == (numSegments - 1) && currentU == 1.0) {
      iHeading = keyFrames[upperKnot].heading;
      iPitch = keyFrames[upperKnot].pitch;
      iBank = keyFrames[upperKnot].bank;
      iPos.set(keyFrames[upperKnot].position);
      iScale.set(keyFrames[upperKnot].scale);

      // if we are somewhere in between the curve
    } else {
      // Get a reference to the current spline segment i.e. the
      // one bounded by lowerKnot and upperKnot
      currentSegment = cubicSplineCurve.getSegment(currentSegmentIndex);

      // interpolate quaternions
      iHeading = currentSegment.getInterpolatedHeading(currentU);
      iPitch = currentSegment.getInterpolatedPitch(currentU);
      iBank = currentSegment.getInterpolatedBank(currentU);

      // interpolate position
      currentSegment.getInterpolatedPositionVector(currentU, iPos);

      // interpolate position
      currentSegment.getInterpolatedScale(currentU, iScale);
      // System.out.println("Pos :" + iPos);
    }

    // Modification by ReubenDB

    if (colorRampingInterpolate == true) {
      float[] curPos = new float[3];
      iPos.get(curPos);

      myColorRamp.getColor(curPos[1], histColor);
      // System.out.println("SETING COLOR:" + histColor + " CurPos: " + curPos[0] + ", " + curPos[1]
      // + ", " + curPos[2]);
      objectCA.setColor(histColor);
      // System.out.println("CurrentAlpha = " + myAlpha.value());
    }

    if (timeDisplayInterpolate == true) {
      myTimeDisplay.updateDisplayFromAlpha(myAlpha.value());
      // System.out.println(myAlpha.value());
    }

    // Generate a transformation matrix in tMat using interpolated
    // heading, pitch and bank
    pitchMat.setIdentity();
    pitchMat.rotX(-iPitch);
    bankMat.setIdentity();
    bankMat.rotZ(iBank);
    tMat.setIdentity();
    tMat.rotY(-iHeading);
    tMat.mul(pitchMat);
    tMat.mul(bankMat);

    // TODO: Vijay - Handle Non-Uniform scale
    // Currently this interpolator does not handle non uniform scale
    // We cheat by just taking the x scale component

    // Scale the transformation matrix
    sMat.set((double) iScale.x);
    tMat.mul(sMat);

    // Set the translation components.
    tMat.m03 = iPos.x;
    tMat.m13 = iPos.y;
    tMat.m23 = iPos.z;
    rotation.set(tMat);

    // construct a Transform3D from:  axis * rotation * axisInverse
    transform.mul(axis, rotation);
    transform.mul(transform, axisInverse);
  }
 private void calcTransformation() {
   calcTransformationBySymmetryAxes();
   // make sure this value is zero. On Linux this value is 0.
   transformationMatrix.setElement(3, 3, 1.0);
 }
  /**
   * Returns a transformation matrix that rotates refPoints to match coordPoints
   *
   * @param refPoints the points to be aligned
   * @param referenceVectors
   * @return
   */
  private Matrix4d alignAxes(Vector3d[] axisVectors, Vector3d[] referenceVectors) {
    Matrix4d m1 = new Matrix4d();
    AxisAngle4d a = new AxisAngle4d();
    Vector3d axis = new Vector3d();

    // calculate rotation matrix to rotate refPoints[0] into coordPoints[0]
    Vector3d v1 = new Vector3d(axisVectors[0]);
    Vector3d v2 = new Vector3d(referenceVectors[0]);
    double dot = v1.dot(v2);
    if (Math.abs(dot) < 0.999) {
      axis.cross(v1, v2);
      axis.normalize();
      a.set(axis, v1.angle(v2));
      m1.set(a);
      // make sure matrix element m33 is 1.0. It's 0 on Linux.
      m1.setElement(3, 3, 1.0);
    } else if (dot > 0) {
      // parallel axis, nothing to do -> identity matrix
      m1.setIdentity();
    } else if (dot < 0) {
      // anti-parallel axis, flip around x-axis
      m1.set(flipX());
    }

    // apply transformation matrix to all refPoints
    m1.transform(axisVectors[0]);
    m1.transform(axisVectors[1]);

    // calculate rotation matrix to rotate refPoints[1] into coordPoints[1]
    v1 = new Vector3d(axisVectors[1]);
    v2 = new Vector3d(referenceVectors[1]);
    Matrix4d m2 = new Matrix4d();
    dot = v1.dot(v2);
    if (Math.abs(dot) < 0.999) {
      axis.cross(v1, v2);
      axis.normalize();
      a.set(axis, v1.angle(v2));
      m2.set(a);
      // make sure matrix element m33 is 1.0. It's 0 on Linux.
      m2.setElement(3, 3, 1.0);
    } else if (dot > 0) {
      // parallel axis, nothing to do -> identity matrix
      m2.setIdentity();
    } else if (dot < 0) {
      // anti-parallel axis, flip around z-axis
      m2.set(flipZ());
    }

    // apply transformation matrix to all refPoints
    m2.transform(axisVectors[0]);
    m2.transform(axisVectors[1]);

    // combine the two rotation matrices
    m2.mul(m1);

    // the RMSD should be close to zero
    Point3d[] axes = new Point3d[2];
    axes[0] = new Point3d(axisVectors[0]);
    axes[1] = new Point3d(axisVectors[1]);
    Point3d[] ref = new Point3d[2];
    ref[0] = new Point3d(referenceVectors[0]);
    ref[1] = new Point3d(referenceVectors[1]);
    if (SuperPosition.rmsd(axes, ref) > 0.1) {
      System.out.println(
          "Warning: AxisTransformation: axes alignment is off. RMSD: "
              + SuperPosition.rmsd(axes, ref));
    }

    return m2;
  }
 private void calcReverseTransformation() {
   reverseTransformationMatrix.invert(transformationMatrix);
 }