/** * Returns the exponential of the Quaternion. * * @see #log() */ public final Quaternion exp() { float theta = PApplet.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); if (theta < 1E-6f) return new Quaternion(this.x, this.y, this.z, PApplet.cos(theta)); else { float coef = PApplet.sin(theta) / theta; return new Quaternion(this.x * coef, this.y * coef, this.z * coef, PApplet.cos(theta)); } }
/** * Returns a random unit Quaternion. * * <p>You can create a randomly directed unit vector using: * * <p>{@code PVector randomDir = new PVector(1.0f, 0.0f, 0.0f);} <br> * {@code randomDir = Quaternion.multiply(Quaternion.randomQuaternion(), randomDir);} */ public static final Quaternion randomQuaternion() { float seed = (float) Math.random(); float r1 = PApplet.sqrt(1.0f - seed); float r2 = PApplet.sqrt(seed); float t1 = 2.0f * PI * (float) Math.random(); float t2 = 2.0f * PI * (float) Math.random(); return new Quaternion( PApplet.sin(t1) * r1, PApplet.cos(t1) * r1, PApplet.sin(t2) * r2, PApplet.cos(t2) * r2); }
// A function to rotate a vector public void rotateVector(PVector v, float theta) { float m = v.mag(); float a = v.heading2D(); a += theta; v.x = m * PApplet.cos(a); v.y = m * PApplet.sin(a); }
/** * Sets the Quaternion as a rotation of {@link #axis() axis} and {@link #angle() angle} (in * radians). * * <p>The {@code axis} does not need to be normalized. A null {@code axis} will result in an * identity Quaternion. * * @param axis the PVector representing the axis * @param angle the angle in radians */ public void fromAxisAngle(PVector axis, float angle) { float norm = axis.mag(); if (norm < 1E-8f) { // Null rotation this.x = 0.0f; this.y = 0.0f; this.z = 0.0f; this.w = 1.0f; } else { float sin_half_angle = PApplet.sin(angle / 2.0f); this.x = sin_half_angle * axis.x / norm; this.y = sin_half_angle * axis.y / norm; this.z = sin_half_angle * axis.z / norm; this.w = PApplet.cos(angle / 2.0f); } }
private final float cos(float a) { return parent.cos(a); }