tobeythorn
11-12-2008, 06:30 PM
I tried quaternion rotations a long time ago, and never got it working. I'm trying it again, from scratch, but seem to be having exactly the same issue: not-so-circular orbits. As a test, I'm incrementing an angle theta each frame and then each frame, using quaternions, rotate a start point by that angle and set a mesh's position as that point. What I want to happen is to see the mesh loop around in circles, depending on which axis i rotate about. I figure this way, I can't possibly have problems with imprecisions accumulating. The thing is, my orbits look more like >'s or weird double loops. I've spent days days checking and rechecking, and am quite frustrated. If you aren't familiar with Objective-C, the notation is [object method(well, message really): parameters].
Here is my relevant code:
//Rotation, done each frame
theta = theta+0.05;
ZQuaternion* newRotation = [[ZQuaternion alloc] initWithValues: cos(theta/2.0): sin(theta/2.0): 0.0: 0.0];
//ZQuaternion* newRotation = [[ZQuaternion alloc] initWithValues: cos(theta/2.0): 0.0: sin(theta/2.0): 0.0];
//ZQuaternion* newRotation = [[ZQuaternion alloc] initWithValues: cos(theta/2.0): 0.0: 0.0: sin(theta/2.0)];
//point to rotate
ZQuaternion* qposition = [[ZQuaternion alloc] initWithValues: 0.0: 0.3: 0.1: 0.6];
ZLeaf* mesh0 = [rootNode childAt: 0];
ZVector3* position = [mesh0 localPosition];
ZQuaternion* newQLocation = [newRotation multiply: [qposition multiply: [newRotation conjugate]]];
position.x = newQLocation.x;
position.y = newQLocation.y;
position.z = newQLocation.z;
//Quaternion Class:
#import "zquaternion.h"
@implementation ZQuaternion
@synthesize w;
@synthesize x;
@synthesize y;
@synthesize z;
-(id) initWithValues: (float) a: (float) b: (float) c: (float) d {
if ((self = [super init])) {
w = a;
x = b;
y = c;
z = d;
}
return self;
}
-(float*) getCArray {
float* cArray = malloc(4*sizeof(float));
*(cArray+0) = w;
*(cArray+1) = x;
*(cArray+2) = y;
*(cArray+3) = z;
return cArray;
}
-(ZQuaternion*) conjugate {
return [[ZQuaternion alloc] initWithValues: w: -x: -y: -z];
}
-(void) unitize {
float magnitude = sqrt( (w*w) + (x*x) + (y*y) + (z*z) );
w /= magnitude;
x /= magnitude;
y /= magnitude;
z /= magnitude;
}
-(ZQuaternion*) multiply: (ZQuaternion*) q {
float a = (w*q.w) - (x+q.x) - (y*q.y) - (z*q.z);
float b = (w*q.x) + (x*q.w) + (y*q.z) - (z*q.y);
float c = (w*q.y) - (x*q.z) + (y*q.w) + (z*q.x);
float d = (w*q.z) + (x*q.y) - (y*q.x) + (z*q.w);
return [[ZQuaternion alloc] initWithValues: a: b: c: d];
}
@end
Thanks for your help,
-Tobey
Here is my relevant code:
//Rotation, done each frame
theta = theta+0.05;
ZQuaternion* newRotation = [[ZQuaternion alloc] initWithValues: cos(theta/2.0): sin(theta/2.0): 0.0: 0.0];
//ZQuaternion* newRotation = [[ZQuaternion alloc] initWithValues: cos(theta/2.0): 0.0: sin(theta/2.0): 0.0];
//ZQuaternion* newRotation = [[ZQuaternion alloc] initWithValues: cos(theta/2.0): 0.0: 0.0: sin(theta/2.0)];
//point to rotate
ZQuaternion* qposition = [[ZQuaternion alloc] initWithValues: 0.0: 0.3: 0.1: 0.6];
ZLeaf* mesh0 = [rootNode childAt: 0];
ZVector3* position = [mesh0 localPosition];
ZQuaternion* newQLocation = [newRotation multiply: [qposition multiply: [newRotation conjugate]]];
position.x = newQLocation.x;
position.y = newQLocation.y;
position.z = newQLocation.z;
//Quaternion Class:
#import "zquaternion.h"
@implementation ZQuaternion
@synthesize w;
@synthesize x;
@synthesize y;
@synthesize z;
-(id) initWithValues: (float) a: (float) b: (float) c: (float) d {
if ((self = [super init])) {
w = a;
x = b;
y = c;
z = d;
}
return self;
}
-(float*) getCArray {
float* cArray = malloc(4*sizeof(float));
*(cArray+0) = w;
*(cArray+1) = x;
*(cArray+2) = y;
*(cArray+3) = z;
return cArray;
}
-(ZQuaternion*) conjugate {
return [[ZQuaternion alloc] initWithValues: w: -x: -y: -z];
}
-(void) unitize {
float magnitude = sqrt( (w*w) + (x*x) + (y*y) + (z*z) );
w /= magnitude;
x /= magnitude;
y /= magnitude;
z /= magnitude;
}
-(ZQuaternion*) multiply: (ZQuaternion*) q {
float a = (w*q.w) - (x+q.x) - (y*q.y) - (z*q.z);
float b = (w*q.x) + (x*q.w) + (y*q.z) - (z*q.y);
float c = (w*q.y) - (x*q.z) + (y*q.w) + (z*q.x);
float d = (w*q.z) + (x*q.y) - (y*q.x) + (z*q.w);
return [[ZQuaternion alloc] initWithValues: a: b: c: d];
}
@end
Thanks for your help,
-Tobey