Sign in to follow this  

Finding angles of rotation between 2x2 vectors

This topic is 4834 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I suck in math. Seriously. I've spent days trying to figure this out, and even after reading a dozen posts on similar subjects, I still can't seem to get this to work. Problem is the following: I have a pair of orientation vectors in 3D - the "Forward" vector (Y), and the "Right" vector (X). Using these I can calculate the Z vector using a cross product.
vX = Normalize(&(*vInX - vPos));
vY = Normalize(&(*vInY - vPos));
vZ = Normalize(&Cross(&vX, &vY));
Now I have a second set of the same vertices, in a different position. They have been rotated somehow, around an arbitrary axis that I don't know. What I need is to figure out the angles I need to use in glRotatef(angle, x, y, z); that would translate point A to point B. I can figure out the way to rotate it around an arbitrary axis using the Cross product to find a rotational axis between two vectors and the Dot product to find the angle. But that only gives me proper rotation on a two dimensional plane, not in 3D space. For example if I Cross & Dot my orientation vectors X(x, y, z) from point A to point B, I will have what I need to rotate the object along the XY plane. If I do the same (0, 0, 0) with orientation vectors Z(x, y, z), I will end up with XZ rotation. Unfortunately both are 2-Dimensional, and I can't combine them without getting odd combination results which are way off from what they should be. Any suggestions?

Share this post


Link to post
Share on other sites
Well, you have AX=B where A is an unknown rotation matrix, X is a matrix whose columns are the points before rotation and B is the points in the same order after rotation. So A=BX^-1. Then the eigenvector for that matrix corresponding to one is the axis of rotation. The formula for constructing an axis angle matrix should give you the means to recover the angle given the axis.

Share this post


Link to post
Share on other sites

And note that there's infinite set of unit-length vectors you can use in glRotate to turn point A to point B .
1: All such vectors lie in plane with normal (A-B) .

(well, proving is left as exercise for the reader :-)

It's not hard to find angle for some vector from that set. For instance,{ vector=(A+B)*0.5 , angle=180 degrees } will turn A to B . As well will do { vector=(A Cross B) , angle=angle_between_a_and_b }. And so-on.

You need at least 2 pairs of points to find rotation,let's name 'em
P,P',Q,Q'
- P rotated to P' and Q rotated to Q'

you just need to find good vector V that can rotate both. It's placed on intersection of set of vectors that can rotate P to P' with set of vectors that can rotate Q to Q'. That is, it's intersection of plane with normal P-P' and other plane with normal Q-Q' .(read 1: and think!)

That is, it's just perpendicular to both plane normals, and it's
V=(P-P')Cross(Q-Q')
i'm bored now and it's night and i worked all day, hope you can find angle yourself. ....but no,i will solve to the end anyway....it's just angle between ( P - V*(P Dot V)/(V Dot V) ) and same formule for P' .

It's just P and P' both projected to plane with normal V, so, after turn by that angle, their projections will match. Simple.

Share this post


Link to post
Share on other sites
Thanks for your replies. LilBudyWizer, you lost me on the word "eigenvector". :)

Dmytry, I got the first formula you posted to work:

vAxis = Normalize(&Cross(&(pLink->vX - vX), &(pLink->vZ - vZ)));


Using the above I am able to find the rotation axis... however your second formula doesn't make much sense? "(V Dot V)" part in particular... Could you post the entire thing? Thanks in advance!

Share this post


Link to post
Share on other sites
I'm writing (V Dot V) because it's sometimes written as
V2
V2
V.length2
|V|
||V||2
It's just squared length, equal to Vx2+Vy2+Vz2
and (V Dot V) is the only notation that makes some sence by itself.

and i meant angle between vectors
( P - V*(P Dot V)/(V Dot V) )
,
( P' - V*(P' Dot V)/(V Dot V) )

You can find angle using
AngleBetweenVectors(A,B)=atan2( A Cross B , A Dot B )

If your V is normalized, then you don't need /(V Dot V) (it's there instead of normalizing)

(i don't sure angle have right sign for glRotate)

Note that it's not guaranteed to turn any Q to Q' because not every two pairs corresponds to valid rotation.

Also your notation
&(pLink->vX - vX), &(pLink->vZ - vZ)
my V is not related to your v* things

Share this post


Link to post
Share on other sites
An eigen vector is a vector x such that Ax=dx for some scalar d. Finding those isn't a simple task so it wouldn't have been a good way to find the axis of rotation. It would be easier to extract the axis and angle from the matrix, but dmytry's method would be even easier. The only problem is if P'-P=0, Q'-Q=0 or P'-P=d(Q'-Q). If any of those are true then your cross product is going to be the zero vector.

Share this post


Link to post
Share on other sites
That's pretty straightforward if you have a math lib available. For instance someone posted a small .cpp file in this math forum a bit earlier. Parse the recent threads.

You have two frames (<=> 3x3 matrices). M1 : X1,Y1,(Z1) and M2 : X2,Y2,(Z2).

(
@Dmytry.
I don't think he wants a rotation between two vectors. It's between two frames ! Thus there is only one matricial solution, and all Euler angles are related to some modulo indetermlination.
)

I suppose that X1.Y1=0 and X2.Y2=0, (perp vectors) and that you have orthonormal or at least orthogonal frames.

All you need is to 'divide' M2 by M1. It can also be expressed with quaternions. In the end all you need is Euler angles.

EA3 = Euler(M2 * tM1)
(
Note that the inverse of an orthonormal matrix is simply its transposition. My math lib contains a mul by transposed, which is very efficiently implemented in SSE and 3DNow since you simply have to multiply and accumulate the. In any case this makes transposition implicit and thus gives it for free
)

Or

EA3 = Euler(Quat(M2), Quat(M1)) done.


In 2D it's very simply expressed by Complex numbers with their dual representation, r*e^it or a+i*b. For rotations, quaternions are the complex numbers of 3D (while they loose commutativity).

Quote:

I suck in math. Seriously. I've spent days trying to figure this out ...

As you can see it would have taken me 10 seconds to write this line of code. It's quite automatic once linear algebra becomes as obvious as elementary calculus. I can't advise you anything else but make the effort to spend a few 'days' learning it. In the end it will save you a lot of time if you plan to write some decent 3D software.

[Edited by - Charles B on September 12, 2004 7:39:30 AM]

Share this post


Link to post
Share on other sites
hmmmmm....i interpreted what he said
Quote:

Now I have a second set of the same vertices, in a different position. They have been rotated somehow, around an arbitrary axis that I don't know. What I need is to figure out the angles I need to use in glRotatef(angle, x, y, z); that would translate point A to point B.


as that he have two sets of points, and he want to find axis/angle that rotated first set to the second. Problem also was i'll-stated because there's infinitely many vectors x,y,z that can rotate A to B (even if we consider only unit-length vectors).

Anyway , doesn't matter, my solution will work if you plug two columns of one matrix as P,Q and same columns of other matrix as P', Q'
(assuming matrices are orthonormal)

Of course it can be done with quaternions, but as he said he just simply want argument to glRotate

(!!!!! and IIRC glRotate(a,x,y,z) rotates around given axis x,y,z by a degrees, it's not related to euler angles !!!!!!)

in fact it's very simple to construct quaternion from axis-and-angle, if he want quaternion instead of arguments for glRotate.

BTW:

There's some problem with my solution, because 2 points is not always enough and ,and also division-by-zero is sometimes possible.

First, for obvious reasons, P and Q must be choosen that P is not parallel to Q, that is ,there must be no scalar a that P=a*Q .


If P-P' = 0 (*): In that cases you just have to rotate around P axis, that is, V=P.
Q-Q' = 0 : same as above,except that V=Q

If both P-P' = 0 and Q-Q'=0, you don't have to rotate at all.

If (P-P')Cross(Q-Q')= 0 , you just have to choose other pair of P,Q,P',Q' .... or i think you can just set V=P-Q .

Should be robust enough now.
*************************************************
(*):better use "if |(P-P').x|<(1E-6)" , same for Q .


edit, and unnecessary final words:

and of course if i have understood what OP said... Instead of doing that crazy(but also correct) vectors stuff,
i also would rather write
M2=Mx*M1
and just find Mx=M2*inverse(M1)
as Charles B absolutely correctly wrote.(and of course, for orthonormal, inverse=transpose.)

Must be because of my participation in threads like "Do it as hard as possible"
(at least i still believe my solution works some precents faster :-)
[grin]

[Edited by - Dmytry on September 12, 2004 7:22:39 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by Dmytry
hmmmmm....i interpreted what he said


He has 3 points per set (Pos, InX, InY) <=> 2 vectors (X,Y) + one translation <=> 1 frame with the normal. I suppose these three points have something to do with 3 triangle vertices, he probably draws them like that in GL. BTW I did not speak of the translations but that's obvious (substraction).

Quote:

You need at least 2 pairs of points to find rotation,let's name 'em
P,P',Q,Q'
- P rotated to P' and Q rotated to Q'


I think your original post, 2 points per set (P,Q) <=> 1 vector and one translation is what I would call the trackball simulation algorithm except here it's affine space while the trackball issue is in linear space, just substract the translations.

Quote:

...because there's infinitely many vectors x,y,z that can rotate A to B


The quaternion that divises the two vectors, gives you the unique minimum rotation between the two vectors.


Quote:

(!!!!! and IIRC glRotate(a,x,y,z) rotates around given axis x,y,z by a degrees, it's not related to euler angles !!!!!!)

Point for you here ;) Was to quick here. Replace :

AR3 = AxisRotation( Quat(M2)/Quat(M1) )

As you suggested AxisRotation() 'cast' is indeed very fast. It mainly requires one atan2(), (and BTW it can be very fastly computed with Taylor, I can give you a very interesting link on it)


Quote:

There's some problem with my solution, ...

First, for obvious reasons, P and Q must be choosen that P is not parallel to Q.


Sure it's supposed to give a frame. The 'triangle' is not degenerate.


Quote:

and of course ... and just find Mx=M2*inverse(M1)
...
(at least i still believe my solution works some precents faster :-)


Converting to quaternions start would give a faster 'division' and the conversion to axis and rotation quasi immediate. Alas the two matrix to quaternions would probably cost a lot.

So the solution with Matrix to Axis Rotation directly is probably the fastest way to do. And if you develop your solution I am pretty certain it gives the same atomic equations and code. (*)

BTW When I'll release my math library, the function documentations will be given with benchmarks (auto generated by the project) with tables for each compiler and processor.


Quote:

Must be because of my participation in threads like "Do it as hard as possible"
(at least i still believe my solution works some precents faster :-)


Yes maybe, but you have not developped the formula enough (*), I'll probably be able to give you the exact answer one month soon :)

Share this post


Link to post
Share on other sites
well,
in code:
(will work only with orthogonal P and Q)

const float smallnumber=1E-6;
inline bool VerySmall(vec3 A){
return abs(A.x)+abs(A.y)+abs(A.z)<smallnumber;
};
inline bool NotVerySmall(vec3 A){
return abs(A.x)+abs(A.y)+abs(A.z)>smallnumber;
};
// don't have the name for it...
DoThisThing(vec3 P,vec3 Q,vec3 P_,vec3 Q_,float &angle, vec3 &axis){
vec3 DP=P-P_, DQ=Q-Q_;vec3 V;
if(NotVerySmall(DP)){// for branch prediction, then part should happen more frequently.
if(NotVerySmall(DQ)){
V=CrossProd(DP,DQ);
if(VerySmall(V)){
if(DotProd(DP,DQ)>0){V=P-Q;}else{V=(P+Q);}
}
}else{//DQ is very small.
V=DQ;
}
}else{//DP is very small
if(NotVerySmall(DQ)){
V=DP;
}else{// both is very small ,no rotation
axis=vec3(1,0,0);angle=0;return();
}
}

Normalize(V);
P-=V*DotProd(P,V);
P_-=V*DotProd(P_,V);
angle=atan2(Length(CrossProd(P,P_)),DotProd(P,P_));
axis=V;
}




i think should work,but haven't checked. Angle returned in radians. Sign of angle may be not what glRotate expects.

It _could be_ faster than matrix-to-quaternion stuff, but there's too many sqrts...and some branching(that actually can make it work faster for special cases).

and of course there's only one shortest-arc rotation ({ vector=(A Cross B) , angle=angle_between_a_and_b }),but we want not shortest arc rotation but rotation that can rotate both to their positions....
edit:some fixes....

Share this post


Link to post
Share on other sites
Dmytry: AngleBetweenVectors(A,B)=atan2( A Cross B , A Dot B )

atan2 function takes 2 doubles, but (A Cross B) would be a vector?

Charles B: Well, what I basically want is this. I have a mesh made up of bodyparts, such as Torso, Arm, Hand, etc. I am not using skinning for multiple reasons, but I want to animate each bodypart seperately in 3D Studio Max, then combine them in my engine using "hookpoints". Hookpoints are basically reference points at joints. For example I have a hookpoint between the torso and an arm. I save the arm along with the hookpoint in one file, torso with the same hookpoint in another file, and I can move them around freely in either file, assuming the hookpoint stays in the same spot relative to the body part.

This allows me to have secondary hookpoints, such as a hookpoint between the arm and a hand. I can animate an arm so that secondary hookpoint will be moved in one of the animations, and I want to attach the hand to that "moved" point. This is where finding arbitrary axis and angle comes into play.

At render time I simply walk down the hiearchy of hookpoints and glTranslate / glRotate each body part into place.

I will look into matrix math more, I guess -- but Euler, Quaternions, all that is foreign to me.

Thanks for your help so far, guys. How I wish I didn't sleep through calculus in high school...

Share this post


Link to post
Share on other sites
Quote:
Original post by MichaelMook
Dmytry: AngleBetweenVectors(A,B)=atan2( A Cross B , A Dot B )

ops,that was a typo - should be
Length(A Cross B) (fixed in code)

Share this post


Link to post
Share on other sites
Here's a quick question. How do I determine if it should be rotating in a positive or negative direction? This way it always rotates in the positive direction no matter what.

float FindRotation(CVector3 *vA1, CVector3 *vA2, CVector3 *vB1, CVector3 *vB2, CVector3 *vAxis)
{
CVector3 v1 = &(*vA2 - vA1);
CVector3 v2 = &(*vB2 - vB1);

if (!v1)
{
if (!v2) { vAxis->Set(0, 0, 1); return 0; }
*vAxis = vA1;
}
else if (!v2) *vAxis = vB1;
else *vAxis = Normalize(v1.Cross(&v2));

if (!(*vAxis)) *vAxis = &Normalize(&(*vA1 - vB1));

v1 = *vA2 - *vAxis * vA2->Dot(vAxis);
v2 = *vA1 - *vAxis * vA1->Dot(vAxis);

CVector3 vCross = v1.Cross(&v2);
float fMag = Magnitude(&vCross);
float fDot = v1.Dot(&v2);
float fAngle = RadToDeg(atan2f(fMag, fDot));

return fAngle;
}

Share this post


Link to post
Share on other sites
P.S. In case I wasn't clear in the last post, I know the direction of the axis itself should logically determine which way it's going to be rotated, but it's not working right it seems. Sometimes it rotates the object properly, other times the angle is the opposite of what it should be...

And since pictures speak louder than words... Here are two.

In this one the object is aligned properly. The colored XYZ axises are put in place based on the actual hookpoint's coordinates (normalized).



And below is a slightly rotated hookpoint. You can see the XYZ hookpoint coordinates didn't move that much, but the rotation axis flipped and the object is no longer aligned. If I was to flip the angle here, it would be fine.



[Edited by - MichaelMook on September 12, 2004 10:50:02 PM]

Share this post


Link to post
Share on other sites
It always gives working axis but sometimes with flipped sign?

I'll check signs soon. Probably bad sign somewhere....

also in my code shortly after posting i added that:
if(VerySmall(V)){
if(DotProd(DP,DQ)>0){V=P-Q;}else{V=(P+Q);}
}
It's for case DP and DQ (*) is parallel because rotation axis is either parallel to difference, but may be parallel to summ.

(but it's now works well only with P,Q that have same length... so if they haven't, it's better to normalize 'em )

(*):corresponds to your v1,v2 before "v1 = *vA2 - *vAxis * vA2->Dot(vAxis);v2 = *vA1 - *vAxis * vA1->Dot(vAxis);"

----

oh, yee, i see the bug.
Quick fix (somewhat hackish), hope will help:
axis=vCross;
(axis must be parallel or anti-parallel to vCross ,and if it's anti-parallel,there's a bug)

so you don't even need separate variable for vCross, and if you like resulting axis to be normalized(doesn't really matter), you can multiply it by (1/fMag) then.

I'd write testing program that rotates coordsystem, rotates again and then compares axis from that routine with actual axis.

also,your code have very many &'s and *'s... maybe it's better not to pass parameters as pointers,but as references?

edit:

1: If it will always rotate the opposite way,flip sign.

2: i just thought that in case thing was rotated by 180 degrees, that damn
vCross will be zero! So use
if(vCross is not very small) axis=vCross;
you still need vCross. if vCross is very small, sign of axis doesn't matter.

or you can just use
if(DotProduct(vCross,axis)<0)axis=-axis;

Hope it was all bugs. Don't really sure now.

3: if that thing will continue to be buggy, produce right and wrong signs, you must better try Charles's solution.
Morale of story: use solution that's shorter to write.
As Charles said ( ...and as i haven't said probably because of misunderstanding... ), just
axisandangle=MatrixToAxisAndAngle(M2*transpose(M1))
where M1 it's original matrix ,M2 it's matrix after unknown rotation.....

And if you want to do it using just 3 points that may not be orthonormal,use
axisandangle=MatrixToAxisAndAngle(M2*inverse(M1))
where M1 in columns have that 3 points prior to rotation, M2 after.

it shouldn't have any bugs of my solution, except that in reality your MatrixToAxisAndAngle may contain bugs as well ... at least MatrixToAxisAndAngle is simpler to test.

[Edited by - Dmytry on September 13, 2004 8:29:31 AM]

Share this post


Link to post
Share on other sites
This does not matter. It's true that an axis rotation is a 'class of equivalence' (math view point). This means that several 'representations' of the same object exist. (1,0,0,90) is the same as (-1,0,0,-90).

This can be seen in how a quaternion is built from and axis-angle :

qx = ax * sin(angle/2)
qy = ay * sin(angle/2)
qz = az * sin(angle/2)
qw = cos(angle/2)

If you change the sign of the axis and the sign of the angle at the same time, you get the same quaternion.

Share this post


Link to post
Share on other sites
Quote:
Original post by MichaelMook
... Hookpoints are basically reference points at joints.
For example I have a hookpoint between the torso and an arm.
...

Can you explain me in this context, the definition of your vPos, vInX, vInY vector parameters ?

vPos = HookPoint position ?
vInX,vInY = Local Axes of the body part ?


Share this post


Link to post
Share on other sites
Quote:
Original post by Charles B
This does not matter. It's true that an axis rotation is a 'class of equivalence' (math view point). This means that several 'representations' of the same object exist. (1,0,0,90) is the same as (-1,0,0,-90).

This can be seen in how a quaternion is built from and axis-angle :

qx = ax * sin(angle/2)
qy = ay * sin(angle/2)
qz = az * sin(angle/2)
qw = cos(angle/2)

If you change the sign of the axis and the sign of the angle at the same time, you get the same quaternion.


I know that if i turn A degrees clockwise around axis, it's same as if i turn A degrees counterclockwise around -axis.

The problem not that sign of everything flips sometimes, it would be perfectly ok.Problem that sign of axis may flip when it's not needed, and may not flip when it's needed.

Angle is always 0..pi ( because magnitude of cross product is always positive, and how it's used in atan2() ), and if we use that vCross as axis, together with that angle ,vCross perfectly changes sign to compensate that angle is always in 0..pi. But in buggy version, "axis" may be sometimes parallel to vCross and sometimes anti-parallel, so it may sometimes turns right, sometimes wrong.

Share this post


Link to post
Share on other sites
Quote:
Original post by Charles B
Quote:
Original post by MichaelMook
... Hookpoints are basically reference points at joints.
For example I have a hookpoint between the torso and an arm.
...

Can you explain me in this context, the definition of your vPos, vInX, vInY vector parameters ?

vPos = HookPoint position ?
vInX,vInY = Local Axes of the body part ?

You guessed it -- vPos is the position of the hookpoint, vInX is the "right", and vInY is the "forward".

Last night just before going to bed I shot myself in the foot by accident -- I deleted all my files. So I've lost 3 days. Gonna be trying to re-do everything later today...

Share this post


Link to post
Share on other sites
So refering to your initial post, letting Vx,Vy,Vz be the columns of your bodypart matrix makes the pure matricial solution obvious and solid.

The problem with P,Q P',Q' is one information (a point) is lost in both frames (source and target). Beyond the sign issue, there are many problems you won't cope with in your animation. Mainly because there is an angular indetermination. This means for instance that an originally cyclic animation my not cycle at all. So keep it simple and try the matrix code. Please tell us back if it worked.

Another question. If I guess well, Vx,Vy,Vz, say matrix M, and Pos is the frame of the 'hand'(example) relative to the 'arm' in stationary position. And target M' and Pos is the frame of the 'hand' animated relative to 'arm'. Right ?

M'/M is the rotation between 'hand' (target) and 'hand' (init) in the frame of 'arm'

Am I right ?


By relative I mean :

/M'
/
-----*-----M
arm hand

Which once arm is also rotated gives :

\ / Frame(arm)*M /M'
\ / /
* and *-----M
/ not / here
/ / M, M' would be absolute

Where Frame(arm)
comes implictely from the
OpenGL matrix stack context.


Else, a suggestion :

Why not replace vPos, vInX, vInY (9 floats) by a precomputed quaternion and position (7 floats) ? It will make the rest far more simple and your code quicker.

"Last night ..."
Sorry to learn that.

Share this post


Link to post
Share on other sites
I just have a question when I see :

AngleBetweenVectors(A,B)=atan2(length(A Cross B) , A Dot B )

Why do this? Is it faster than

AngleBetweenVectors(A,B)=acos(A Dot B / |A||B| ) ??
I mean I guess you have to divide, but isnt that what atan2 does?

Both have a length calculation, a dot product, perhaps a divide. The top just has the extra cross product.

Share this post


Link to post
Share on other sites
acos work bad for small angles. Derivative of cosine is 0 at 0, and so, derivative of acos is infinite.

atan2 it's not a simplified-to-use acos. It's actually not that simple to simulate atan2 yourself, it's something like
float atan2(float y,float x){
if(y>0)
{
if(x>0)
{
if(x>y)
{
return atan(y/x);
}
else
{
return (pi/2)-atan(x/y);
}
}
else
{

other blabla for every octant, don't want to type.

}
}
else
{
if(x>0)
{

}
else
{

}
}
}

Also, as it turned out, we need to ajust sign of axis, so cross product is needed anyway...

btw,to Charles:

P,P', Q,Q' is enough for matrix solution , too. Just set R = CrossProduct(P,Q) and R' = CrossProduct(P',Q')
and use P,Q,R as columns in matrix .
But of course we have 3 orthonormal points anyway, so probably it's not needed to calculate R from two.

And yes, with 2 points we have less information, but if our "unknown transform" is rotation only, it's enough (if needed, can calculate 3rd point using cross product). If unknown transform is linear transform by arbitrary matrix, then 2 points is not enough and we really need at least 3 points.

Matrix solution may have minor problems with getting axis-and-angle from matrix. Probably matrix-to-axis_and_angle is based on matrix-to-quaternion.....
look there . edit: looked, derivations is right, must work. Except one special case for small angles. If matrix is slightly out-of-shape, it may try to compute
acos(1.000000001)
that's not good at all.

Share this post


Link to post
Share on other sites
Thanks! It works perfectly now. :) Here's the complete function. Operator '!' is set to check if the vector is too small (XYZ values are just about 0).

float FindRotation(CVector3 *vA1, CVector3 *vA2, CVector3 *vB1, CVector3 *vB2, CVector3 *vAxis)
{
CVector3 v1 = &(*vA2 - vA1);
CVector3 v2 = &(*vB2 - vB1);

if (!v1) // If v1 is too small too close to 0
{
if (!v2) { vAxis->Set(0, 0, 1); return 0; }
*vAxis = vA1;
}
else if (!v2) *vAxis = vB1;
else *vAxis = Normalize(&v1.Cross(&v2));

if (!(*vAxis)) *vAxis = &Normalize(&(*vA1 - vB1));

v1 = *vA2 - *vAxis * vA2->Dot(vAxis);
v2 = *vA1 - *vAxis * vA1->Dot(vAxis);

CVector3 vCross = v1.Cross(&v2);
float fAngle = RadToDeg(atan2f(Magnitude(&vCross), v1.Dot(&v2)));
if (vCross.Dot(vAxis) > 0) fAngle = -fAngle;

return fAngle;
}


I guess the next step is trying to figure out how the matrices work and how I can fit them into this whole thing...

Quote:
Another question. If I guess well, Vx,Vy,Vz, say matrix M, and Pos is the frame of the 'hand'(example) relative to the 'arm' in stationary position. And target M' and Pos is the frame of the 'hand' animated relative to 'arm'. Right ?

It's relative to the predecessor, yes. I start at the top of the hiearchy and translate/rotate by the calculated difference every step, encapsulated in a fresh glPushMatrix() / glPopMatrix(). This way I get the relative position, and draw the actual mesh (such as the "hand") in that relative location. That's the idea anyway... I'll try to get it all working tonight and let you know how that worked out.

I realize using matrices would probably be easier, but as I said, math is my weak side and I have to do some research to figure out where values should go if I was using matrix transformation / multiplication. I actually started my 4x4 matrix class yesterday, but I lost it in the morning in the ... *cough* wipe.

Thanks for everyone's help!

Share this post


Link to post
Share on other sites
P.S. Here are two more functions if someone wants to understand where the values came from.

Hookpoint::Hookpoint(const char *sInName, Mesh *pM, CVector3 *vLeft, CVector3 *vCenter, CVector3 *vTop)
{
strcpy(sName, sInName);
pMesh = pM;
vPos = *vCenter;
vX = Normalize(&(*vLeft - vCenter));
vY = Normalize(&(*vTop - vCenter));
vZ = Normalize(&vX.Cross(&vY));
pLink = NULL;
}

void Hookpoint::Link(Hookpoint *pIn)
{
Break();
pLink = pIn;
pLink->pMesh->Hiearchial(true);
vTranslate = pLink->vPos - vPos;
fAngle = FindRotation(&vX, &pLink->vX, &vZ, &pLink->vZ, &vAxis);
}

Share this post


Link to post
Share on other sites

This topic is 4834 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this