Merge branch 'master' of https://source.jalview.org/git/jalviewjs.git
[jalviewjs.git] / src / javajs / util / M3.java
index 102cf0d..8d46569 100644 (file)
-/*\r
-   Copyright (C) 1997,1998,1999\r
-   Kenji Hiranabe, Eiwa System Management, Inc.\r
-\r
-   This program is free software.\r
-   Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),\r
-   conforming to the Java(TM) 3D API specification by Sun Microsystems.\r
-\r
-   Permission to use, copy, modify, distribute and sell this software\r
-   and its documentation for any purpose is hereby granted without fee,\r
-   provided that the above copyright notice appear in all copies and\r
-   that both that copyright notice and this permission notice appear\r
-   in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.\r
-   makes no representations about the suitability of this software for any\r
-   purpose.  It is provided "AS IS" with NO WARRANTY.\r
-*/\r
-package javajs.util;\r
-\r
-import java.io.Serializable;\r
-\r
-\r
-\r
-/**\r
- * A single precision floating point 3 by 3 matrix.\r
- * \r
- * @author Kenji hiranabe\r
- * \r
- *         additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique\r
- *         constructor and method names for the optimization of compiled\r
- *         JavaScript using Java2Script\r
- *         \r
- *         \r
- */\r
-public class M3 extends M34 implements Serializable {\r
-\r
-  /**\r
-   * Constructs and initializes a Matrix3f to all zeros.\r
-   * @j2sIgnore\r
-   */\r
-  public M3() {\r
-  }\r
-\r
-  /**\r
-   * Constructs and initializes a Matrix3f from the specified 9 element array.\r
-   * this.m00 =v[0], this.m01=v[1], etc.\r
-   * \r
-   * @param v\r
-   *        the array of length 9 containing in order\r
-   * @return m\r
-   */\r
-  public static M3 newA9(float[] v) {\r
-    M3 m = new M3();\r
-    m.setA(v);\r
-    return m;\r
-  }\r
-  \r
-  /**\r
-   * Constructs a new matrix with the same values as the Matrix3f parameter.\r
-   * \r
-   * @param m1\r
-   *        The source matrix.\r
-   * @return m\r
-   */\r
-  public static M3 newM3(M3 m1) {\r
-    M3 m = new M3();\r
-    if (m1 == null) {\r
-      m.setScale(1);\r
-      return m;\r
-    }\r
-    m.m00 = m1.m00;\r
-    m.m01 = m1.m01;\r
-    m.m02 = m1.m02;\r
-\r
-    m.m10 = m1.m10;\r
-    m.m11 = m1.m11;\r
-    m.m12 = m1.m12;\r
-\r
-    m.m20 = m1.m20;\r
-    m.m21 = m1.m21;\r
-    m.m22 = m1.m22;\r
-    return m;\r
-  }\r
-\r
-  /**\r
-   * Sets this Matrix3f to a scalar * Identity.\r
-   * @param scale \r
-   */\r
-  public void setScale(float scale) {\r
-    clear33();\r
-    m00 = m11 = m22 = scale;\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to the double value of the Matrix3f argument.\r
-   * \r
-   * @param m1\r
-   *        the matrix3f\r
-   */\r
-  public void setM3(M34 m1) {\r
-    setM33(m1);\r
-  }\r
-  /**\r
-   * Sets the values in this Matrix3f equal to the row-major array parameter\r
-   * (ie, the first four elements of the array will be copied into the first row\r
-   * of this matrix, etc.).\r
-   * \r
-   * @param m\r
-   */\r
-  public void setA(float m[]) {\r
-    m00 = m[0];\r
-    m01 = m[1];\r
-    m02 = m[2];\r
-    m10 = m[3];\r
-    m11 = m[4];\r
-    m12 = m[5];\r
-    m20 = m[6];\r
-    m21 = m[7];\r
-    m22 = m[8];\r
-  }\r
-\r
-  /**\r
-   * Sets the specified element of this matrix3d to the value provided.\r
-   * \r
-   * @param row\r
-   *        the row number to be modified (zero indexed)\r
-   * @param col\r
-   *        the column number to be modified (zero indexed)\r
-   * @param v\r
-   *        the new value\r
-   */\r
-  public void setElement(int row, int col, float v) {\r
-    set33(row, col, v);\r
-  }\r
-\r
-  /**\r
-   * Retrieves the value at the specified row and column of this matrix.\r
-   * \r
-   * @param row\r
-   *        the row number to be retrieved (zero indexed)\r
-   * @param col\r
-   *        the column number to be retrieved (zero indexed)\r
-   * @return the value at the indexed element\r
-   */\r
-  public float getElement(int row, int col) {\r
-    return get33(row, col);\r
-  }\r
-\r
-  /**\r
-   * Sets the specified row of this matrix3d to the three values provided.\r
-   * \r
-   * @param row\r
-   *        the row number to be modified (zero indexed)\r
-   * @param x\r
-   *        the first column element\r
-   * @param y\r
-   *        the second column element\r
-   * @param z\r
-   *        the third column element\r
-   */\r
-  public void setRow(int row, float x, float y, float z) {\r
-    switch (row) {\r
-    case 0:\r
-      m00 = x;\r
-      m01 = y;\r
-      m02 = z;\r
-      return;\r
-    case 1:\r
-      m10 = x;\r
-      m11 = y;\r
-      m12 = z;\r
-      return;\r
-    case 2:\r
-      m20 = x;\r
-      m21 = y;\r
-      m22 = z;\r
-      return;\r
-    default:\r
-      err();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Sets the specified row of this matrix3d to the Vector provided.\r
-   * \r
-   * @param row\r
-   *        the row number to be modified (zero indexed)\r
-   * @param v\r
-   *        the replacement row\r
-   */\r
-  public void setRowV(int row, T3 v) {\r
-    switch (row) {\r
-    case 0:\r
-      m00 = v.x;\r
-      m01 = v.y;\r
-      m02 = v.z;\r
-      return;\r
-    case 1:\r
-      m10 = v.x;\r
-      m11 = v.y;\r
-      m12 = v.z;\r
-      return;\r
-    case 2:\r
-      m20 = v.x;\r
-      m21 = v.y;\r
-      m22 = v.z;\r
-      return;\r
-    default:\r
-      err();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Sets the specified row of this matrix3d to the four values provided.\r
-   * \r
-   * @param row\r
-   *        the row number to be modified (zero indexed)\r
-   * @param v\r
-   *        the replacement row\r
-   */\r
-  public void setRowA(int row, float v[]) {\r
-    setRow33(row, v);\r
-  }\r
-\r
-  /**\r
-   * Copies the matrix values in the specified row into the array parameter.\r
-   * \r
-   * @param row\r
-   *        the matrix row\r
-   * @param v\r
-   *        The array into which the matrix row values will be copied\r
-   */\r
-  @Override\r
-  public void getRow(int row, float v[]) {\r
-    getRow33(row, v);\r
-  }\r
-\r
-  /**\r
-   * Sets the specified column of this matrix3d to the three values provided.\r
-   * \r
-   * @param column\r
-   *        the column number to be modified (zero indexed)\r
-   * @param x\r
-   *        the first row element\r
-   * @param y\r
-   *        the second row element\r
-   * @param z\r
-   *        the third row element\r
-   */\r
-  public void setColumn3(int column, float x, float y, float z) {\r
-    switch (column) {\r
-    case 0:\r
-      m00 = x;\r
-      m10 = y;\r
-      m20 = z;\r
-      break;\r
-    case 1:\r
-      m01 = x;\r
-      m11 = y;\r
-      m21 = z;\r
-      break;\r
-    case 2:\r
-      m02 = x;\r
-      m12 = y;\r
-      m22 = z;\r
-      break;\r
-    default:\r
-      err();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Sets the specified column of this matrix3d to the vector provided.\r
-   * \r
-   * @param column\r
-   *        the column number to be modified (zero indexed)\r
-   * @param v\r
-   *        the replacement column\r
-   */\r
-  public void setColumnV(int column, T3 v) {\r
-    switch (column) {\r
-    case 0:\r
-      m00 = v.x;\r
-      m10 = v.y;\r
-      m20 = v.z;\r
-      break;\r
-    case 1:\r
-      m01 = v.x;\r
-      m11 = v.y;\r
-      m21 = v.z;\r
-      break;\r
-    case 2:\r
-      m02 = v.x;\r
-      m12 = v.y;\r
-      m22 = v.z;\r
-      break;\r
-    default:\r
-      err();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Copies the matrix values in the specified column into the vector parameter.\r
-   * \r
-   * @param column\r
-   *        the matrix column\r
-   * @param v\r
-   *        The vector into which the matrix row values will be copied\r
-   */\r
-  public void getColumnV(int column, T3 v) {\r
-    switch (column) {\r
-    case 0:\r
-      v.x = m00;\r
-      v.y = m10;\r
-      v.z = m20;\r
-      break;\r
-    case 1:\r
-      v.x = m01;\r
-      v.y = m11;\r
-      v.z = m21;\r
-      break;\r
-    case 2:\r
-      v.x = m02;\r
-      v.y = m12;\r
-      v.z = m22;\r
-      break;\r
-    default:\r
-      err();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * Sets the specified column of this matrix3d to the four values provided.\r
-   * \r
-   * @param column\r
-   *        the column number to be modified (zero indexed)\r
-   * @param v\r
-   *        the replacement column\r
-   */\r
-  public void setColumnA(int column, float v[]) {\r
-    setColumn33(column, v);\r
-  }\r
-\r
-  /**\r
-   * Copies the matrix values in the specified column into the array parameter.\r
-   * \r
-   * @param column\r
-   *        the matrix column\r
-   * @param v\r
-   *        The array into which the matrix row values will be copied\r
-   */\r
-  public void getColumn(int column, float v[]) {\r
-    getColumn33(column, v);\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to sum of itself and matrix m1.\r
-   * \r
-   * @param m1\r
-   *        the other matrix\r
-   */\r
-  public void add(M3 m1) {\r
-    add33(m1);\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to the matrix difference of itself and matrix\r
-   * m1 (this = this - m1).\r
-   * \r
-   * @param m1\r
-   *        the other matrix\r
-   */\r
-  public void sub(M3 m1) {\r
-    sub33(m1);\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to its transpose.\r
-   */\r
-  public void transpose() {\r
-    transpose33();\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to the transpose of the argument matrix\r
-   * \r
-   * @param m1\r
-   *        the matrix to be transposed\r
-   */\r
-  public void transposeM(M3 m1) {\r
-    // alias-safe\r
-    setM33(m1);\r
-    transpose33();\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to the matrix inverse of the passed matrix\r
-   * m1.\r
-   * \r
-   * @param m1\r
-   *        the matrix to be inverted\r
-   */\r
-  public void invertM(M3 m1) {\r
-    setM33(m1);\r
-    invert();\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to its inverse.\r
-   */\r
-  public void invert() {\r
-    double s = determinant3();\r
-    if (s == 0.0)\r
-      return;\r
-    s = 1 / s;\r
-    // alias-safe way.\r
-    set9(m11 * m22 - m12 * m21, m02 * m21 - m01 * m22, m01 * m12 - m02 * m11,\r
-        m12 * m20 - m10 * m22, m00 * m22 - m02 * m20, m02 * m10 - m00 * m12,\r
-        m10 * m21 - m11 * m20, m01 * m20 - m00 * m21, m00 * m11 - m01 * m10);\r
-    scale((float) s);\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to a rotation matrix about the x axis by the\r
-   * passed angle.\r
-   * \r
-   * @param angle\r
-   *        the angle to rotate about the X axis in radians\r
-   * @return this\r
-   */\r
-  public M3 setAsXRotation(float angle) {\r
-    setXRot(angle);\r
-    return this;\r
-  }\r
-  \r
-  /**\r
-   * Sets the value of this matrix to a rotation matrix about the y axis by the\r
-   * passed angle.\r
-   * \r
-   * @param angle\r
-   *        the angle to rotate about the Y axis in radians\r
-   * @return this\r
-   */\r
-  public M3 setAsYRotation(float angle) {\r
-    setYRot(angle);\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to a rotation matrix about the z axis by the\r
-   * passed angle.\r
-   * \r
-   * @param angle\r
-   *        the angle to rotate about the Z axis in radians\r
-   * @return this\r
-   */\r
-  public M3 setAsZRotation(float angle) {\r
-    setZRot(angle);\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * Multiplies each element of this matrix by a scalar.\r
-   * \r
-   * @param scalar\r
-   *        The scalar multiplier.\r
-   */\r
-  public void scale(float scalar) {\r
-    mul33(scalar);\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to the result of multiplying itself with\r
-   * matrix m1.\r
-   * \r
-   * @param m1\r
-   *        the other matrix\r
-   */\r
-  public void mul(M3 m1) {\r
-    mul2(this, m1);\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to the result of multiplying the two argument\r
-   * matrices together.\r
-   * \r
-   * @param m1\r
-   *        the first matrix\r
-   * @param m2\r
-   *        the second matrix\r
-   */\r
-  public void mul2(M3 m1, M3 m2) {\r
-    // alias-safe way.\r
-    set9(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20, m1.m00 * m2.m01\r
-        + m1.m01 * m2.m11 + m1.m02 * m2.m21, m1.m00 * m2.m02 + m1.m01 * m2.m12\r
-        + m1.m02 * m2.m22,\r
-\r
-    m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20, m1.m10 * m2.m01\r
-        + m1.m11 * m2.m11 + m1.m12 * m2.m21, m1.m10 * m2.m02 + m1.m11 * m2.m12\r
-        + m1.m12 * m2.m22,\r
-\r
-    m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20, m1.m20 * m2.m01\r
-        + m1.m21 * m2.m11 + m1.m22 * m2.m21, m1.m20 * m2.m02 + m1.m21 * m2.m12\r
-        + m1.m22 * m2.m22);\r
-  }\r
-\r
-  /**\r
-   * Returns true if the Object o is of type Matrix3f and all of the data\r
-   * members of t1 are equal to the corresponding data members in this Matrix3f.\r
-   * \r
-   * @param o\r
-   *        the object with which the comparison is made.\r
-   */\r
-  @Override\r
-  public boolean equals(Object o) {\r
-    if (!(o instanceof M3))\r
-      return false;\r
-    M3 m = (M3) o;\r
-    return m00 == m.m00 && m01 == m.m01 && m02 == m.m02 && m10 == m.m10\r
-        && m11 == m.m11 && m12 == m.m12 && m20 == m.m20 && m21 == m.m21\r
-        && m22 == m.m22;\r
-  }\r
-\r
-  /**\r
-   * Returns a hash number based on the data values in this object. Two\r
-   * different Matrix3f objects with identical data values (ie, returns true for\r
-   * equals(Matrix3f) ) will return the same hash number. Two objects with\r
-   * different data members may return the same hash value, although this is not\r
-   * likely.\r
-   * \r
-   * @return the integer hash value\r
-   */\r
-  @Override\r
-  public int hashCode() {\r
-    return T3.floatToIntBits0(m00) ^ T3.floatToIntBits0(m01)\r
-        ^ T3.floatToIntBits0(m02) ^ T3.floatToIntBits0(m10)\r
-        ^ T3.floatToIntBits0(m11) ^ T3.floatToIntBits0(m12)\r
-        ^ T3.floatToIntBits0(m20) ^ T3.floatToIntBits0(m21)\r
-        ^ T3.floatToIntBits0(m22);\r
-  }\r
-\r
-  /**\r
-   * Sets this matrix to all zeros.\r
-   */\r
-  public void setZero() {\r
-    clear33();\r
-  }\r
-\r
-  /**\r
-   * Sets 9 values\r
-   * \r
-   * @param m00\r
-   * @param m01\r
-   * @param m02\r
-   * @param m10\r
-   * @param m11\r
-   * @param m12\r
-   * @param m20\r
-   * @param m21\r
-   * @param m22\r
-   */\r
-  private void set9(float m00, float m01, float m02, float m10, float m11,\r
-                   float m12, float m20, float m21, float m22) {\r
-    this.m00 = m00;\r
-    this.m01 = m01;\r
-    this.m02 = m02;\r
-    this.m10 = m10;\r
-    this.m11 = m11;\r
-    this.m12 = m12;\r
-    this.m20 = m20;\r
-    this.m21 = m21;\r
-    this.m22 = m22;\r
-  }\r
-\r
-  /**\r
-   * Returns a string that contains the values of this Matrix3f.\r
-   * \r
-   * @return the String representation\r
-   */\r
-  @Override\r
-  public String toString() {\r
-    return "[\n  [" + m00 + "\t" + m01 + "\t" + m02 + "]" + "\n  [" + m10\r
-        + "\t" + m11 + "\t" + m12 + "]" + "\n  [" + m20 + "\t" + m21 + "\t"\r
-        + m22 + "] ]";\r
-  }\r
-\r
-  /**\r
-   * Sets the value of this matrix to the matrix conversion of the single\r
-   * precision axis and angle argument.\r
-   * \r
-   * @param a\r
-   *        the axis and angle to be converted\r
-   * @return this\r
-   */\r
-  public M3 setAA(A4 a) {\r
-    setAA33(a);\r
-    return this;\r
-  }\r
-\r
-  /**\r
-   * 3D ball rotation from dx dy in-plane mouse motion\r
-   * adapted from Andrew Hanson\r
-   * Computer Graphics beyond the Third Dimension:\r
-   * Geometry, Orientation Control, and Rendering for\r
-   * Graphics in Dimensions Greater than Three\r
-   * Course Notes for SIGGRAPH ’98\r
-   * http://www.cse.ohio-state.edu/~hwshen/888_su02/hanson_note.pdf\r
-   * \r
-   * @param responseFactor Jmol uses 0.02 here\r
-   * @param dx\r
-   * @param dy\r
-   * @return true if successful; false if not;\r
-   */\r
-  public boolean setAsBallRotation(float responseFactor, float dx, float dy) {\r
-    float r = (float) Math.sqrt(dx * dx + dy * dy);\r
-    float th =  r * responseFactor;\r
-    if (th == 0) {\r
-      setScale(1);\r
-      return false;\r
-    }\r
-    float c = (float) Math.cos(th);\r
-    float s = (float) Math.sin(th);\r
-    float nx = -dy / r;\r
-    float ny = dx / r;\r
-    float c1 = c - 1;\r
-    m00 = 1 + c1 * nx * nx;\r
-    m01 = m10 = c1 * nx * ny;\r
-    m20 = -(m02 = s * nx);\r
-    m11 = 1 + c1 * ny * ny;\r
-    m21 = -(m12 = s * ny);\r
-    m22 = c;\r
-    return true;\r
-  }\r
-\r
-  public boolean isRotation() {\r
-    return (Math.abs(determinant3() - 1) < 0.001f);\r
-  }\r
-\r
-}\r
+/*
+   Copyright (C) 1997,1998,1999
+   Kenji Hiranabe, Eiwa System Management, Inc.
+
+   This program is free software.
+   Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+   conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+   Permission to use, copy, modify, distribute and sell this software
+   and its documentation for any purpose is hereby granted without fee,
+   provided that the above copyright notice appear in all copies and
+   that both that copyright notice and this permission notice appear
+   in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+   makes no representations about the suitability of this software for any
+   purpose.  It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+import java.io.Serializable;
+
+
+
+/**
+ * A single precision floating point 3 by 3 matrix.
+ * 
+ * @author Kenji hiranabe
+ * 
+ *         additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
+ *         constructor and method names for the optimization of compiled
+ *         JavaScript using Java2Script
+ *         
+ *         
+ */
+public class M3 extends M34 implements Serializable {
+
+  /**
+   * Constructs and initializes a Matrix3f to all zeros.
+   * @j2sIgnore
+   */
+  public M3() {
+  }
+
+  /**
+   * Constructs and initializes a Matrix3f from the specified 9 element array.
+   * this.m00 =v[0], this.m01=v[1], etc.
+   * 
+   * @param v
+   *        the array of length 9 containing in order
+   * @return m
+   */
+  public static M3 newA9(float[] v) {
+    M3 m = new M3();
+    m.setA(v);
+    return m;
+  }
+  
+  /**
+   * Constructs a new matrix with the same values as the Matrix3f parameter.
+   * 
+   * @param m1
+   *        The source matrix.
+   * @return m
+   */
+  public static M3 newM3(M3 m1) {
+    M3 m = new M3();
+    if (m1 == null) {
+      m.setScale(1);
+      return m;
+    }
+    m.m00 = m1.m00;
+    m.m01 = m1.m01;
+    m.m02 = m1.m02;
+
+    m.m10 = m1.m10;
+    m.m11 = m1.m11;
+    m.m12 = m1.m12;
+
+    m.m20 = m1.m20;
+    m.m21 = m1.m21;
+    m.m22 = m1.m22;
+    return m;
+  }
+
+  /**
+   * Sets this Matrix3f to a scalar * Identity.
+   * @param scale 
+   */
+  public void setScale(float scale) {
+    clear33();
+    m00 = m11 = m22 = scale;
+  }
+
+  /**
+   * Sets the value of this matrix to the double value of the Matrix3f argument.
+   * 
+   * @param m1
+   *        the matrix3f
+   */
+  public void setM3(M34 m1) {
+    setM33(m1);
+  }
+  /**
+   * Sets the values in this Matrix3f equal to the row-major array parameter
+   * (ie, the first four elements of the array will be copied into the first row
+   * of this matrix, etc.).
+   * 
+   * @param m
+   */
+  public void setA(float m[]) {
+    m00 = m[0];
+    m01 = m[1];
+    m02 = m[2];
+    m10 = m[3];
+    m11 = m[4];
+    m12 = m[5];
+    m20 = m[6];
+    m21 = m[7];
+    m22 = m[8];
+  }
+
+  /**
+   * Sets the specified element of this matrix3d to the value provided.
+   * 
+   * @param row
+   *        the row number to be modified (zero indexed)
+   * @param col
+   *        the column number to be modified (zero indexed)
+   * @param v
+   *        the new value
+   */
+  public void setElement(int row, int col, float v) {
+    set33(row, col, v);
+  }
+
+  /**
+   * Retrieves the value at the specified row and column of this matrix.
+   * 
+   * @param row
+   *        the row number to be retrieved (zero indexed)
+   * @param col
+   *        the column number to be retrieved (zero indexed)
+   * @return the value at the indexed element
+   */
+  public float getElement(int row, int col) {
+    return get33(row, col);
+  }
+
+  /**
+   * Sets the specified row of this matrix3d to the three values provided.
+   * 
+   * @param row
+   *        the row number to be modified (zero indexed)
+   * @param x
+   *        the first column element
+   * @param y
+   *        the second column element
+   * @param z
+   *        the third column element
+   */
+  public void setRow(int row, float x, float y, float z) {
+    switch (row) {
+    case 0:
+      m00 = x;
+      m01 = y;
+      m02 = z;
+      return;
+    case 1:
+      m10 = x;
+      m11 = y;
+      m12 = z;
+      return;
+    case 2:
+      m20 = x;
+      m21 = y;
+      m22 = z;
+      return;
+    default:
+      err();
+    }
+  }
+
+  /**
+   * Sets the specified row of this matrix3d to the Vector provided.
+   * 
+   * @param row
+   *        the row number to be modified (zero indexed)
+   * @param v
+   *        the replacement row
+   */
+  public void setRowV(int row, T3 v) {
+    switch (row) {
+    case 0:
+      m00 = v.x;
+      m01 = v.y;
+      m02 = v.z;
+      return;
+    case 1:
+      m10 = v.x;
+      m11 = v.y;
+      m12 = v.z;
+      return;
+    case 2:
+      m20 = v.x;
+      m21 = v.y;
+      m22 = v.z;
+      return;
+    default:
+      err();
+    }
+  }
+
+  /**
+   * Sets the specified row of this matrix3d to the four values provided.
+   * 
+   * @param row
+   *        the row number to be modified (zero indexed)
+   * @param v
+   *        the replacement row
+   */
+  public void setRowA(int row, float v[]) {
+    setRow33(row, v);
+  }
+
+  /**
+   * Copies the matrix values in the specified row into the array parameter.
+   * 
+   * @param row
+   *        the matrix row
+   * @param v
+   *        The array into which the matrix row values will be copied
+   */
+  @Override
+  public void getRow(int row, float v[]) {
+    getRow33(row, v);
+  }
+
+  /**
+   * Sets the specified column of this matrix3d to the three values provided.
+   * 
+   * @param column
+   *        the column number to be modified (zero indexed)
+   * @param x
+   *        the first row element
+   * @param y
+   *        the second row element
+   * @param z
+   *        the third row element
+   */
+  public void setColumn3(int column, float x, float y, float z) {
+    switch (column) {
+    case 0:
+      m00 = x;
+      m10 = y;
+      m20 = z;
+      break;
+    case 1:
+      m01 = x;
+      m11 = y;
+      m21 = z;
+      break;
+    case 2:
+      m02 = x;
+      m12 = y;
+      m22 = z;
+      break;
+    default:
+      err();
+    }
+  }
+
+  /**
+   * Sets the specified column of this matrix3d to the vector provided.
+   * 
+   * @param column
+   *        the column number to be modified (zero indexed)
+   * @param v
+   *        the replacement column
+   */
+  public void setColumnV(int column, T3 v) {
+    switch (column) {
+    case 0:
+      m00 = v.x;
+      m10 = v.y;
+      m20 = v.z;
+      break;
+    case 1:
+      m01 = v.x;
+      m11 = v.y;
+      m21 = v.z;
+      break;
+    case 2:
+      m02 = v.x;
+      m12 = v.y;
+      m22 = v.z;
+      break;
+    default:
+      err();
+    }
+  }
+
+  /**
+   * Copies the matrix values in the specified column into the vector parameter.
+   * 
+   * @param column
+   *        the matrix column
+   * @param v
+   *        The vector into which the matrix row values will be copied
+   */
+  public void getColumnV(int column, T3 v) {
+    switch (column) {
+    case 0:
+      v.x = m00;
+      v.y = m10;
+      v.z = m20;
+      break;
+    case 1:
+      v.x = m01;
+      v.y = m11;
+      v.z = m21;
+      break;
+    case 2:
+      v.x = m02;
+      v.y = m12;
+      v.z = m22;
+      break;
+    default:
+      err();
+    }
+  }
+
+  /**
+   * Sets the specified column of this matrix3d to the four values provided.
+   * 
+   * @param column
+   *        the column number to be modified (zero indexed)
+   * @param v
+   *        the replacement column
+   */
+  public void setColumnA(int column, float v[]) {
+    setColumn33(column, v);
+  }
+
+  /**
+   * Copies the matrix values in the specified column into the array parameter.
+   * 
+   * @param column
+   *        the matrix column
+   * @param v
+   *        The array into which the matrix row values will be copied
+   */
+  public void getColumn(int column, float v[]) {
+    getColumn33(column, v);
+  }
+
+  /**
+   * Sets the value of this matrix to sum of itself and matrix m1.
+   * 
+   * @param m1
+   *        the other matrix
+   */
+  public void add(M3 m1) {
+    add33(m1);
+  }
+
+  /**
+   * Sets the value of this matrix to the matrix difference of itself and matrix
+   * m1 (this = this - m1).
+   * 
+   * @param m1
+   *        the other matrix
+   */
+  public void sub(M3 m1) {
+    sub33(m1);
+  }
+
+  /**
+   * Sets the value of this matrix to its transpose.
+   */
+  public void transpose() {
+    transpose33();
+  }
+
+  /**
+   * Sets the value of this matrix to the transpose of the argument matrix
+   * 
+   * @param m1
+   *        the matrix to be transposed
+   */
+  public void transposeM(M3 m1) {
+    // alias-safe
+    setM33(m1);
+    transpose33();
+  }
+
+  /**
+   * Sets the value of this matrix to the matrix inverse of the passed matrix
+   * m1.
+   * 
+   * @param m1
+   *        the matrix to be inverted
+   */
+  public void invertM(M3 m1) {
+    setM33(m1);
+    invert();
+  }
+
+  /**
+   * Sets the value of this matrix to its inverse.
+   */
+  public void invert() {
+    double s = determinant3();
+    if (s == 0.0)
+      return;
+    s = 1 / s;
+    // alias-safe way.
+    set9(m11 * m22 - m12 * m21, m02 * m21 - m01 * m22, m01 * m12 - m02 * m11,
+        m12 * m20 - m10 * m22, m00 * m22 - m02 * m20, m02 * m10 - m00 * m12,
+        m10 * m21 - m11 * m20, m01 * m20 - m00 * m21, m00 * m11 - m01 * m10);
+    scale((float) s);
+  }
+
+  /**
+   * Sets the value of this matrix to a rotation matrix about the x axis by the
+   * passed angle.
+   * 
+   * @param angle
+   *        the angle to rotate about the X axis in radians
+   * @return this
+   */
+  public M3 setAsXRotation(float angle) {
+    setXRot(angle);
+    return this;
+  }
+  
+  /**
+   * Sets the value of this matrix to a rotation matrix about the y axis by the
+   * passed angle.
+   * 
+   * @param angle
+   *        the angle to rotate about the Y axis in radians
+   * @return this
+   */
+  public M3 setAsYRotation(float angle) {
+    setYRot(angle);
+    return this;
+  }
+
+  /**
+   * Sets the value of this matrix to a rotation matrix about the z axis by the
+   * passed angle.
+   * 
+   * @param angle
+   *        the angle to rotate about the Z axis in radians
+   * @return this
+   */
+  public M3 setAsZRotation(float angle) {
+    setZRot(angle);
+    return this;
+  }
+
+  /**
+   * Multiplies each element of this matrix by a scalar.
+   * 
+   * @param scalar
+   *        The scalar multiplier.
+   */
+  public void scale(float scalar) {
+    mul33(scalar);
+  }
+
+  /**
+   * Sets the value of this matrix to the result of multiplying itself with
+   * matrix m1.
+   * 
+   * @param m1
+   *        the other matrix
+   */
+  public void mul(M3 m1) {
+    mul2(this, m1);
+  }
+
+  /**
+   * Sets the value of this matrix to the result of multiplying the two argument
+   * matrices together.
+   * 
+   * @param m1
+   *        the first matrix
+   * @param m2
+   *        the second matrix
+   */
+  public void mul2(M3 m1, M3 m2) {
+    // alias-safe way.
+    set9(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20, m1.m00 * m2.m01
+        + m1.m01 * m2.m11 + m1.m02 * m2.m21, m1.m00 * m2.m02 + m1.m01 * m2.m12
+        + m1.m02 * m2.m22,
+
+    m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20, m1.m10 * m2.m01
+        + m1.m11 * m2.m11 + m1.m12 * m2.m21, m1.m10 * m2.m02 + m1.m11 * m2.m12
+        + m1.m12 * m2.m22,
+
+    m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20, m1.m20 * m2.m01
+        + m1.m21 * m2.m11 + m1.m22 * m2.m21, m1.m20 * m2.m02 + m1.m21 * m2.m12
+        + m1.m22 * m2.m22);
+  }
+
+  /**
+   * Returns true if the Object o is of type Matrix3f and all of the data
+   * members of t1 are equal to the corresponding data members in this Matrix3f.
+   * 
+   * @param o
+   *        the object with which the comparison is made.
+   */
+  @Override
+  public boolean equals(Object o) {
+    if (!(o instanceof M3))
+      return false;
+    M3 m = (M3) o;
+    return m00 == m.m00 && m01 == m.m01 && m02 == m.m02 && m10 == m.m10
+        && m11 == m.m11 && m12 == m.m12 && m20 == m.m20 && m21 == m.m21
+        && m22 == m.m22;
+  }
+
+  /**
+   * Returns a hash number based on the data values in this object. Two
+   * different Matrix3f objects with identical data values (ie, returns true for
+   * equals(Matrix3f) ) will return the same hash number. Two objects with
+   * different data members may return the same hash value, although this is not
+   * likely.
+   * 
+   * @return the integer hash value
+   */
+  @Override
+  public int hashCode() {
+    return T3.floatToIntBits0(m00) ^ T3.floatToIntBits0(m01)
+        ^ T3.floatToIntBits0(m02) ^ T3.floatToIntBits0(m10)
+        ^ T3.floatToIntBits0(m11) ^ T3.floatToIntBits0(m12)
+        ^ T3.floatToIntBits0(m20) ^ T3.floatToIntBits0(m21)
+        ^ T3.floatToIntBits0(m22);
+  }
+
+  /**
+   * Sets this matrix to all zeros.
+   */
+  public void setZero() {
+    clear33();
+  }
+
+  /**
+   * Sets 9 values
+   * 
+   * @param m00
+   * @param m01
+   * @param m02
+   * @param m10
+   * @param m11
+   * @param m12
+   * @param m20
+   * @param m21
+   * @param m22
+   */
+  private void set9(float m00, float m01, float m02, float m10, float m11,
+                   float m12, float m20, float m21, float m22) {
+    this.m00 = m00;
+    this.m01 = m01;
+    this.m02 = m02;
+    this.m10 = m10;
+    this.m11 = m11;
+    this.m12 = m12;
+    this.m20 = m20;
+    this.m21 = m21;
+    this.m22 = m22;
+  }
+
+  /**
+   * Returns a string that contains the values of this Matrix3f.
+   * 
+   * @return the String representation
+   */
+  @Override
+  public String toString() {
+    return "[\n  [" + m00 + "\t" + m01 + "\t" + m02 + "]" + "\n  [" + m10
+        + "\t" + m11 + "\t" + m12 + "]" + "\n  [" + m20 + "\t" + m21 + "\t"
+        + m22 + "] ]";
+  }
+
+  /**
+   * Sets the value of this matrix to the matrix conversion of the single
+   * precision axis and angle argument.
+   * 
+   * @param a
+   *        the axis and angle to be converted
+   * @return this
+   */
+  public M3 setAA(A4 a) {
+    setAA33(a);
+    return this;
+  }
+
+  /**
+   * 3D ball rotation from dx dy in-plane mouse motion
+   * adapted from Andrew Hanson
+   * Computer Graphics beyond the Third Dimension:
+   * Geometry, Orientation Control, and Rendering for
+   * Graphics in Dimensions Greater than Three
+   * Course Notes for SIGGRAPH ’98
+   * http://www.cse.ohio-state.edu/~hwshen/888_su02/hanson_note.pdf
+   * 
+   * @param responseFactor Jmol uses 0.02 here
+   * @param dx
+   * @param dy
+   * @return true if successful; false if not;
+   */
+  public boolean setAsBallRotation(float responseFactor, float dx, float dy) {
+    float r = (float) Math.sqrt(dx * dx + dy * dy);
+    float th =  r * responseFactor;
+    if (th == 0) {
+      setScale(1);
+      return false;
+    }
+    float c = (float) Math.cos(th);
+    float s = (float) Math.sin(th);
+    float nx = -dy / r;
+    float ny = dx / r;
+    float c1 = c - 1;
+    m00 = 1 + c1 * nx * nx;
+    m01 = m10 = c1 * nx * ny;
+    m20 = -(m02 = s * nx);
+    m11 = 1 + c1 * ny * ny;
+    m21 = -(m12 = s * ny);
+    m22 = c;
+    return true;
+  }
+
+  public boolean isRotation() {
+    return (Math.abs(determinant3() - 1) < 0.001f);
+  }
+
+}