Created
November 9, 2012 09:34
-
-
Save mxrguspxrt/4044808 to your computer and use it in GitHub Desktop.
java2-home4.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.*; | |
import java.util.regex.*; | |
/** Quaternions. Basic operations. */ | |
public class Quaternion { | |
public double realPart; | |
public double i; | |
public double j; | |
public double k; | |
// TODO!!! Your fields here! | |
/** Constructor from four double values. | |
* @param a real part | |
* @param b imaginary part i | |
* @param c imaginary part j | |
* @param d imaginary part k | |
*/ | |
public Quaternion (double a, double b, double c, double d) { | |
this.realPart = a; | |
this.i = b; | |
this.j = c; | |
this.k = d; | |
} | |
/** Real part of the quaternion. | |
* @return real part | |
*/ | |
public double getRpart() { | |
return this.realPart; | |
} | |
/** Imaginary part i of the quaternion. | |
* @return imaginary part i | |
*/ | |
public double getIpart() { | |
return this.i; | |
} | |
/** Imaginary part j of the quaternion. | |
* @return imaginary part j | |
*/ | |
public double getJpart() { | |
return this.j; | |
} | |
/** Imaginary part k of the quaternion. | |
* @return imaginary part k | |
*/ | |
public double getKpart() { | |
return this.k; | |
} | |
/** Conversion of the quaternion to the string. | |
* @return a string form of this quaternion: | |
* "a+bi+cj+dk" | |
* (without any brackets) | |
*/ | |
@Override | |
public String toString() { | |
return this.realPart + "+" + this.i + "i+" + this.j + "j+" + this.k + "k"; | |
} | |
/** Conversion from the string to the quaternion. | |
* Reverse to <code>toString</code> method. | |
* @throws IllegalArgumentException if string s does not represent | |
* a quaternion (defined by the <code>toString</code> method) | |
* @param s string of form produced by the <code>toString</code> method | |
* @return a quaternion represented by string s | |
*/ | |
public static Quaternion valueOf (String s) { | |
Pattern p = Pattern.compile("(\\d+\\.\\d+)+(\\d+\\.\\d+)i+(\\d+\\.\\d+)j+(\\d+\\.\\d+)k"); | |
Matcher m = p.matcher(s); | |
try { | |
m.find(); | |
} catch(Exception e) {} | |
if(m.groupCount()!=4) throw new IllegalArgumentException(); | |
String realNumberAndRest[] = s.split("\\+", 2); | |
double realNumber = Double.valueOf(realNumberAndRest[0]); | |
String iAndRest[] = realNumberAndRest[1].split("i\\+", 2); | |
double i = Double.valueOf(iAndRest[0]); | |
String jAndRest[] = iAndRest[1].split("j\\+", 2); | |
double j = Double.valueOf(jAndRest[0]); | |
String kAndRest[] = jAndRest[1].split("k", 2); | |
double k = Double.valueOf(kAndRest[0]); | |
return new Quaternion(realNumber, i, j, k); | |
} | |
/** Clone of the quaternion. | |
* @return independent clone of <code>this</code> | |
*/ | |
@Override | |
public Object clone() throws CloneNotSupportedException { | |
return new Quaternion(realPart, i, j, k); | |
} | |
/** Test whether the quaternion is zero. | |
* @return true, if the real part and all the imaginary parts are (close to) zero | |
*/ | |
public boolean isZero() { | |
boolean is = doubleCompare(0, this.realPart) && doubleCompare(0, this.i) && doubleCompare(0, j) && doubleCompare(0, this.k); | |
return is; | |
} | |
/** Conjugate of the quaternion. Expressed by the formula | |
* conjugate(a+bi+cj+dk) = a-bi-cj-dk | |
* @return conjugate of <code>this</code> | |
*/ | |
public Quaternion conjugate() { | |
return new Quaternion(this.realPart, -this.i, -this.j, -this.k); | |
} | |
/** Opposite of the quaternion. Expressed by the formula | |
* opposite(a+bi+cj+dk) = -a-bi-cj-dk | |
* @return quaternion <code>-this</code> | |
*/ | |
public Quaternion opposite() { | |
return new Quaternion(-this.realPart, -this.i, -this.j, -this.k); | |
} | |
/** Sum of quaternions. Expressed by the formula | |
* (a1+b1i+c1j+d1k) + (a2+b2i+c2j+d2k) = (a1+a2) + (b1+b2)i + (c1+c2)j + (d1+d2)k | |
* @param q addend | |
* @return quaternion <code>this+q</code> | |
*/ | |
public Quaternion plus (Quaternion q) { | |
return new Quaternion(this.realPart+q.realPart, this.i+q.i, this.j+q.j, this.k+q.k); | |
} | |
/** Product of quaternions. Expressed by the formula | |
* (a1+b1i+c1j+d1k) * (a2+b2i+c2j+d2k) = (a1a2-b1b2-c1c2-d1d2) + (a1b2+b1a2+c1d2-d1c2)i + | |
* (a1c2-b1d2+c1a2+d1b2)j + (a1d2+b1c2-c1b2+d1a2)k | |
* @param q factor | |
* @return quaternion <code>this*q</code> | |
*/ | |
public Quaternion times(Quaternion q) { | |
double a1 = this.realPart; | |
double b1 = this.i; | |
double c1 = this.j; | |
double d1 = this.k; | |
double a2 = q.realPart; | |
double b2 = q.i; | |
double c2 = q.j; | |
double d2 = q.k; | |
double realPart = a1*a2-b1*b2-c1*c2-d1*d2; | |
double i = a1*b2+b1*a2+c1*d2-d1*c2; | |
double j = a1*c2-b1*d2+c1*a2+d1*b2; | |
double k = a1*d2+b1*c2-c1*b2+d1*a2; | |
return new Quaternion(realPart, i, j, k); | |
} | |
/** Multiplication by a coefficient. | |
* @param r coefficient | |
* @return quaternion <code>this*r</code> | |
*/ | |
public Quaternion times (double r) { | |
return new Quaternion(this.realPart*r, this.i*r, this.j*r, this.k*r); | |
} | |
/** Inverse of the quaternion. Expressed by the formula | |
* 1/(a+bi+cj+dk) = a/(a*a+b*b+c*c+d*d) + | |
* ((-b)/(a*a+b*b+c*c+d*d))i + ((-c)/(a*a+b*b+c*c+d*d))j + ((-d)/(a*a+b*b+c*c+d*d))k | |
* @return quaternion <code>1/this</code> | |
* 1 / new Quaternion(a, bi, cj, dk); | |
*/ | |
public Quaternion inverse() { | |
double x = this.realPart*this.realPart + this.i*this.i + this.j*this.j + this.k*this.k; | |
return new Quaternion(this.realPart/x, (-this.i)/x, (-this.j)/x, (-this.k)/x); | |
} | |
/** Difference of quaternions. Expressed as addition to the opposite. | |
* @param q subtrahend | |
* @return quaternion <code>this-q</code> | |
*/ | |
public Quaternion minus(Quaternion q) { | |
return this.plus(q.opposite()); | |
} | |
/** Right quotient of quaternions. Expressed as multiplication to the inverse. | |
* @param q (right) divisor | |
* @return quaternion <code>this*inverse(q)</code> | |
*/ | |
public Quaternion divideByRight (Quaternion q) { | |
return this.times(q.inverse()); | |
} | |
/** Left quotient of quaternions. | |
* @param q (left) divisor | |
* @return quaternion <code>inverse(q)*this</code> | |
*/ | |
public Quaternion divideByLeft (Quaternion q) { | |
return q.inverse().times(this); | |
} | |
public static boolean doubleCompare(double a, double b){ | |
if(Math.abs(a-b)<0.0001) return true; | |
return false; | |
} | |
/** Equality test of quaternions. Difference of equal numbers | |
* is (close to) zero. | |
* @param qo second quaternion | |
* @return logical value of the expression <code>this.equals(qo)</code> | |
*/ | |
public boolean equals (Object q) { | |
if(q instanceof Quaternion) { | |
if(doubleCompare(this.realPart, ((Quaternion) q).getRpart()) && doubleCompare(this.i, ((Quaternion) q).getIpart()) && doubleCompare(this.j, ((Quaternion) q).getJpart()) && doubleCompare(this.k, ((Quaternion) q).getKpart())) | |
return true; | |
} | |
return false; | |
} | |
/** Dot product of quaternions. (p*conjugate(q) + q*conjugate(p))/2 | |
* @param q factor | |
* @return dot product of this and q | |
*/ | |
public Quaternion dotMult (Quaternion q) { | |
Quaternion x = this.times(q.conjugate()); | |
return x.plus(x).times(0.5); | |
} | |
/** Integer hashCode has to be the same for equal objects. | |
* @return hashcode | |
*/ | |
@Override | |
public int hashCode() { | |
return new Double(this.realPart).hashCode() + new Double(this.i).hashCode() + new Double(this.j).hashCode() + new Double(this.k).hashCode(); | |
} | |
/** Norm of the quaternion. Expressed by the formula | |
* norm(a+bi+cj+dk) = Math.sqrt(a*a+b*b+c*c+d*d) | |
* @return norm of <code>this</code> (norm is a real number) | |
*/ | |
public double norm() { | |
return Math.sqrt(this.realPart*this.realPart+this.i*this.i+this.j*this.j+this.k*this.k); | |
} | |
/** Main method for testing purposes. | |
* @param arg command line parameters | |
*/ | |
public static void main (String[] arg) { | |
Quaternion arv1 = new Quaternion (-1., 1, 2., -2.); | |
if (arg.length > 0) | |
arv1 = valueOf (arg[0]); | |
System.out.println ("first: " + arv1.toString()); | |
System.out.println ("real: " + arv1.getRpart()); | |
System.out.println ("imagi: " + arv1.getIpart()); | |
System.out.println ("imagj: " + arv1.getJpart()); | |
System.out.println ("imagk: " + arv1.getKpart()); | |
System.out.println ("isZero: " + arv1.isZero()); | |
System.out.println ("conjugate: " + arv1.conjugate()); | |
System.out.println ("opposite: " + arv1.opposite()); | |
System.out.println ("hashCode: " + arv1.hashCode()); | |
Quaternion res = null; | |
try { | |
res = (Quaternion)arv1.clone(); | |
} catch (CloneNotSupportedException e) {}; | |
System.out.println ("clone equals to original: " + res.equals (arv1)); | |
System.out.println ("clone is not the same object: " + (res!=arv1)); | |
System.out.println ("hashCode: " + res.hashCode()); | |
res = valueOf (arv1.toString()); | |
System.out.println ("string conversion equals to original: " | |
+ res.equals (arv1)); | |
Quaternion arv2 = new Quaternion (1., -2., -1., 2.); | |
if (arg.length > 1) | |
arv2 = valueOf (arg[1]); | |
System.out.println ("second: " + arv2.toString()); | |
System.out.println ("hashCode: " + arv2.hashCode()); | |
System.out.println ("equals: " + arv1.equals (arv2)); | |
res = arv1.plus (arv2); | |
System.out.println ("plus: " + res); | |
System.out.println ("times: " + arv1.times (arv2)); | |
System.out.println ("minus: " + arv1.minus (arv2)); | |
double mm = arv1.norm(); | |
System.out.println ("norm: " + mm); | |
System.out.println ("inverse: " + arv1.inverse()); | |
System.out.println ("divideByRight: " + arv1.divideByRight (arv2)); | |
System.out.println ("divideByLeft: " + arv1.divideByLeft (arv2)); | |
System.out.println ("dotMult: " + arv1.dotMult (arv2)); | |
Quaternion fag1 = new Quaternion(1.12, 2, 3, 4); | |
Quaternion fag2 = new Quaternion(1.12, 2, 3, 4); | |
System.out.println("OMF" + fag1.equals(fag2)); | |
Quaternion fag3 = new Quaternion(1.12, 2, 3, 4); | |
Quaternion fag4 = new Quaternion(1.12, 2.1, 3, 4); | |
System.out.println("OMF" + fag3.equals(fag4)); | |
boolean wtf = Quaternion.valueOf("2.0+3.0i+6.0j+24.0k").equals(Quaternion.valueOf("2.0000000000000004+3.0i+6.0j+24.0k")); | |
System.out.println("WTTTF" + wtf); | |
} | |
} | |
// end of file |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment