I'm hoping to get a handle on this subject so I've been digging.
This is a rather down to earth tutorial to introduce people:
http://www.cprogramming.com/tutorial/3d/quaternions.html
I started to code up the description but then I found this:
http://www.javaworld.com/javaworld/jw-08-1998/jw-08-step_p.html
It has some quaternion rotation code near the bottom of the document. I can't get it to work though. this is the error I get:
Code:
Temp/build/Temporary_8047_6539.java:7:7:7:28: Semantic Error: The method "newRotation" is not static, and cannot be accessed in this static context.
To make short work of anyone trying to help me I've put the Triple and Quaternion classes together below with how far I've got in making the code work:
Code:
void setup(){
size(200,200,P3D);
}
void draw(){
Triple loc = new Triple (0.5, 3.0, -2.0);
rot = Quaternion.newRotation (-.82, 1.0, 0.0, 0.0);
Triple[][] eyeMap = new Triple[steps + 1][steps + 1];
for (int i = 0; i <= steps; ++ i) {
for (int j = 0; j <= steps; ++ j) {
Triple p = map[i][j];
Triple t = p.subtract (loc);
Triple r = rot.rotate (t);
eyeMap[i][j] = r;
}
}
}
public class Quaternion {
private double w, x, y, z;
private Quaternion inverse;
public Quaternion (double w, double x, double y, double z) {
this.w = w;
this.x = x;
this.y = y;
this.z = z;
this.inverse = null;
}
public Quaternion inverse () {
double scale = 1.0 / (x * x + y * y + z * z + w * w);
return new Quaternion (w * scale, - x * scale, - y * scale, - z * scale);
}
public Quaternion multiply (Quaternion q) {
double qx = q.x, qy = q.y, qz = q.z, qw = q.w;
double rw = w * qw - x * qx - y * qy - z * qz;
double rx = w * qx + x * qw + y * qz - z * qy;
double ry = w * qy + y * qw + z * qx - x * qz;
double rz = w * qz + z * qw + x * qy - y * qx;
return new Quaternion (rw, rx, ry, rz);
}
public Triple rotate (Triple t) {
if (inverse == null)
inverse = inverse ();
double iw = inverse.w, ix = inverse.x, iy = inverse.y, iz = inverse.z;
double tx = t.x, ty = t.y, tz = t.z;
double aw = - x * tx - y * ty - z * tz;
double ax = w * tx + y * tz - z * ty;
double ay = w * ty + z * tx - x * tz;
double az = w * tz + x * ty - y * tx;
double bx = aw * ix + ax * iw + ay * iz - az * iy;
double by = aw * iy + ay * iw + az * ix - ax * iz;
double bz = aw * iz + az * iw + ax * iy - ay * ix;
return new Triple (bx, by, bz);
}
public Quaternion newRotation (double r, double x, double y, double z) {
double len = Math.sqrt (x * x + y * y + z * z);
double sin = Math.sin (r / 2.0);
double cos = Math.cos (r / 2.0);
double tmp = sin / len;
return new Quaternion (cos, x * tmp, y * tmp, z * tmp);
}
}
public class Triple {
private double x, y, z;
public Triple (double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public Triple add (Triple t) {
return new Triple (x + t.x, y + t.y, z + t.z);
}
public Triple subtract (Triple t) {
return new Triple (x - t.x, y - t.y, z - t.z);
}
public Triple cross (Triple t) {
return new Triple (y * t.z - z * t.y, z * t.x - x * t.z,
x * t.y - y * t.x);
}
public double dot (Triple t) {
return x * t.x + y * t.y + z * t.z;
}
public double length2 () {
return dot (this);
}
public Triple normalize () {
return scale (1.0 / Math.sqrt (length2 ()));
}
public Triple scale (double scale) {
return new Triple (x * scale, y * scale, z * scale);
}
}
I'd been wondering also if I can get some 4D rotation out of these classes. I assume it's possible as quaternions are four dimensional locales. I'm wondering also if I can use the quaternion equations to reverse the roation idea and infer where a point of view is from an object's changed dimensions seen at an angle.
At the very least I'd like to get the code running. Then I can answer the more difficult questions myself by experimentation. Thanks in advance.