JAL-1807 Bob's first commit -- Applet loaded; needs image
[jalview.git] / src / javajs / util / M3.java
diff --git a/src/javajs/util/M3.java b/src/javajs/util/M3.java
new file mode 100644 (file)
index 0000000..8d46569
--- /dev/null
@@ -0,0 +1,638 @@
+/*
+   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);
+  }
+
+}