Matrix Rotations?
by Dave Calabrese · in Torque Game Engine · 01/17/2005 (12:45 am) · 19 replies
Been staring at this code since early in the afternoon, think I'm about ready to ask for some help. =)
I have Point A and I need to rotate Object B around Point A in the center. I understand I need to use 'Matrix Rotations' with the Matrix Create function. I am, in now way, a math-genius, however I am trying to learn.
Here is the code that I am using:
This works PERFECTLY for the 'radianRotation' part, and rotates my object exactly as needed. This also works with the P.X part. My big problem is the P.Y! How the heck do I make it rotate around that center object properly??
I have Point A and I need to rotate Object B around Point A in the center. I understand I need to use 'Matrix Rotations' with the Matrix Create function. I am, in now way, a math-genius, however I am trying to learn.
Here is the code that I am using:
function getNodeTransform(%Node)
{
%column = %Node.column;
%row = %Node.row;
//Get the orientation of the Node itself
%rotation = 30 * %column;
%radianRotation = mDegToRad(%rotation);
//Get our 'X' Position
if(%row == 0)
{
%X = $worldPositions.MasterNode + 29.0673;
}
if(%row != 0)
{
%StartPosition = $worldPositions.MasterNode + 29.0673;
%AddDistance = 5.3244 * %row;
%X = %StartPosition + %AddDistance;
}
//Get our 'Y' Position
//%Y = "-501.933";
%mat = MatrixCreate($worldPositions.MasterNode,%rotation);
error("Matrix = " @ %mat);
%Y = getWord(%mat,1);
%Node.position = %X SPC %Y SPC " 156.87";
%Node.rotataion = "0 0 1" SPC %radianRotation;
%transform = %X SPC %Y SPC "156.87" SPC "0 0 1" SPC %radianRotation;
return %transform;
}This works PERFECTLY for the 'radianRotation' part, and rotates my object exactly as needed. This also works with the P.X part. My big problem is the P.Y! How the heck do I make it rotate around that center object properly??
About the author
Recent Threads
#2
Just trying to get my head around what you are trying to do here.
It looks like you are just rotating in the x,y plane, ie ignoring z. So if we were looking down on the object, 'O' it would look a bit like this (excuse ascii art): Center of rotation is the point, 'P'.
After we rotate the object by some angle around the point P, it looks like this:
You can do simple rotations like this without matrices. Let me know if I'm on the right track and I will continue.
01/17/2005 (11:29 am)
Hi Dave,Just trying to get my head around what you are trying to do here.
It looks like you are just rotating in the x,y plane, ie ignoring z. So if we were looking down on the object, 'O' it would look a bit like this (excuse ascii art): Center of rotation is the point, 'P'.
P O
After we rotate the object by some angle around the point P, it looks like this:
O P
You can do simple rotations like this without matrices. Let me know if I'm on the right track and I will continue.
#3
As I stated before, I've got the individual rotation of O around its own access perfect, and I've got its distance from P perfect. (So I've done a private rotation, then a transform). So, it's the final rotation - the one that will give me the Position.Y number, that I still need.
01/17/2005 (11:53 am)
You got it! That's exactly what I need!As I stated before, I've got the individual rotation of O around its own access perfect, and I've got its distance from P perfect. (So I've done a private rotation, then a transform). So, it's the final rotation - the one that will give me the Position.Y number, that I still need.
#4
First we need the current transform of the object we want to rotate (this is the starting position and orientation). If the object already exists, you can use the getTransform() method.
Next we need to know how much to rotate the object around P:
We are rotating around the Z axis (0,0,1), so the first matrix is:
This matrix describes the point we are rotating around, as well as the rotation axis, and how much to rotate.
The second matrix is the current node transform, with the position replaced with the vector pointing from P to O:
Now do the rotation:
Clear as mud, right? ;D
01/17/2005 (12:41 pm)
After looking at it a bit more, it's probably easier to use matrices after all.First we need the current transform of the object we want to rotate (this is the starting position and orientation). If the object already exists, you can use the getTransform() method.
%objTransform = obj.getTransform();
Next we need to know how much to rotate the object around P:
%rotAngle = 1.57; // angle in radians
We are rotating around the Z axis (0,0,1), so the first matrix is:
%rot = %P.x SPC %P.y SPC %P.z SPC 0 SPC 0 SPC 1 SPC %rotAngle;
This matrix describes the point we are rotating around, as well as the rotation axis, and how much to rotate.
The second matrix is the current node transform, with the position replaced with the vector pointing from P to O:
%start = VectorSub(objectPosition, P) SPC getWords(%objTransform, 3, 6);
Now do the rotation:
%nodeTransform = MatrixMultiply(%rot, %start);
Clear as mud, right? ;D
#5
Lemme ask a few questions...
Under:
What is 'P'? The 'ObjectPosition'... that is the position of the center object, or the object I am rotating? And what exactly is the position number I should be giving it...? The value of the getTransform? Just the X/Y/Z position of it?
This is the code I made from what you said:
The console echo is ALWAYS identical to %position.
Thanks again for helping the 'math retarded' over here! =)
01/17/2005 (1:00 pm)
Clear as mud, exactly! ;)Lemme ask a few questions...
Under:
%start = VectorSub(objectPosition, P) SPC getWords(%objTransform, 3, 6);
What is 'P'? The 'ObjectPosition'... that is the position of the center object, or the object I am rotating? And what exactly is the position number I should be giving it...? The value of the getTransform? Just the X/Y/Z position of it?
This is the code I made from what you said:
%position = "43.4 -501.883 154.593";
%P.X = "43.4";
%P.Y = "-501.883";
%P.z = "154.593";
%objTransform = %node.getTransform();
//%rotAngle = 1.57;
%rot = %P.x SPC %P.y SPC %P.z SPC 0 SPC 0 SPC 1 SPC %radianRotation;
%start = VectorSub(%position, P) SPC getWords($objTransform, 3, 6);
%nodeTransform = MatrixMultiply(%rot, %start);
error("Transform = " @ %nodeTransform);The console echo is ALWAYS identical to %position.
Thanks again for helping the 'math retarded' over here! =)
#6
objectPosition is the initial position of the object you are rotating. You can get it from the transform by:
It is exactly right that the console echo is identical to %position. Since in the code above you had P = %position, you were rotating the zero vector, so you would always end up at the center of rotation!
01/17/2005 (1:07 pm)
P is the position of the point you are rotating around.objectPosition is the initial position of the object you are rotating. You can get it from the transform by:
%objectPosition = getWords(%objTransform, 0, 2);
It is exactly right that the console echo is identical to %position. Since in the code above you had P = %position, you were rotating the zero vector, so you would always end up at the center of rotation!
#7
The value that %nodeTransform becomes, I see, is something such as this:
76.987 0 1 1 0 0 0
Does that sound right so far...? I mean, how that I have that number, is that the value that I add/subtract to my original position to transform it, or is there something else I do with that?
01/17/2005 (1:17 pm)
Okay, I think I've ALMOST got it...The value that %nodeTransform becomes, I see, is something such as this:
76.987 0 1 1 0 0 0
Does that sound right so far...? I mean, how that I have that number, is that the value that I add/subtract to my original position to transform it, or is there something else I do with that?
#8
If it is still not working, could you post the following values:
P (the point you are rotating around)
objTransform (the transform of the object before rotation)
rotAngle (the amount to rotate in radians)
I will take a look to see if there is something funny going on.
01/17/2005 (1:26 pm)
%nodeTransform should be the final rotated position and orientation, just return it directly from your getNodeTransform function.If it is still not working, could you post the following values:
P (the point you are rotating around)
objTransform (the transform of the object before rotation)
rotAngle (the amount to rotate in radians)
I will take a look to see if there is something funny going on.
#9
Is that... even close to what I'm supposed to be doing?
01/17/2005 (1:27 pm)
And... here is my updated code. Something seems wrong... the objects are all being drawn on a single straight line, and they aren't rotataing around the center point, and they are _WAY_ off, WAY north of the center point...%column = %node.column;
%row = %node.row;
//Get the orientation of the node itself
%rotation = 30 * %column;
%radianRotation = mDegToRad(%rotation);
//Get our 'X' Position
if(%row == 0)
{
%X = $worldPositions.CenterNode + 29.0673;
}
if(%row != 0)
{
%StartPosition = $worldPositions.CenterNode + 29.0673;
%AddDistance = 5.3244 * %row;
%X = %StartPosition + %AddDistance;
}
%currentLocation = %X @ "-501.883 154.593";
//Get our 'Y' Position
%objTransform = %node.getTransform();
%objectPosition = getWords(%objTransform, 0, 2);
%P.X = getWords($worldPositions.centerNode,0);
%P.Y = getWords($worldPositions.centerNode,1);
%P.z = getWords($worldPositions.centerNode,2);
//%rotAngle = 1.57 * %column;
%rot = %P.x SPC %P.y SPC %P.z SPC 0 SPC 0 SPC 1 SPC %radianRotation;
%start = VectorSub(%currentLocation, $worldPositions.centerNode) SPC getWords($objTransform, 3, 6);
%nodeTransform = MatrixMultiply(%rot, %start);
error("Transform = " @ %nodeTransform);Is that... even close to what I'm supposed to be doing?
#10
%objTransform is the same number as above, however the 'X' has been changed in the 'Get our 'X' position' section.
01/17/2005 (1:41 pm)
$worldPositions.centerNode == "43.4 -501.883 154.593"%objTransform is the same number as above, however the 'X' has been changed in the 'Get our 'X' position' section.
#11
I'm at work so can't run TGE to check syntax - hopefully it is ok.
01/17/2005 (1:44 pm)
Run this code and post the values that are echoed.// get amount to rotate object
%rotation = 30 * %column;
%radianRotation = mDegToRad(%rotation);
error("Rotation angle = " @ %radianRotation);
// get center of rotation
%p = $worldPositions.centerNode;
error("Rotation center = " @ " %p);
// get objects initial position and orientation
%objTransform = %node.getTransform();
error("Object initial transform = " @ %objTransform);
// do the rotation
%objectPosition = getWords(%objTransform, 0, 2);
%rot = %p SPC 0 SPC 0 SPC 1 SPC %radianRotation;
%start = VectorSub(%objectPosition, %p) SPC getWords($objTransform, 3, 6);
%nodeTransform = MatrixMultiply(%rot, %start);
error("Objects new transform = " @ %nodeTransform);I'm at work so can't run TGE to check syntax - hopefully it is ok.
#12
Rotation angle = 0
Rotation center = 43.4 -501.883 154.593
Object initial transform = 43.4 -501.883 154.593 1 0 0 0
Objects new transform = 43.4 -501.883 154.593 1 0 0 0
Transform = 29.0673 0 1 1 0 0 0
01/17/2005 (2:02 pm)
And the result IS:Rotation angle = 0
Rotation center = 43.4 -501.883 154.593
Object initial transform = 43.4 -501.883 154.593 1 0 0 0
Objects new transform = 43.4 -501.883 154.593 1 0 0 0
Transform = 29.0673 0 1 1 0 0 0
#13
Where did that last line: "Transform = 29.0673 0 1 1 0 0 0" come from?
Maybe I need a bit more explanation of what you are trying to achieve. I see from the first post you have rows and columns? Are you trying to arrange a grid of objects? Or arrange objects in a circular arc around a position?
Do you use MSN? This might be faster without the post delay.
01/17/2005 (2:08 pm)
With a rotation angle of 0, you get no rotation, and the object is already at the center of rotation, so that's why the 'new' transform is the same as the 'initial'.Where did that last line: "Transform = 29.0673 0 1 1 0 0 0" come from?
Maybe I need a bit more explanation of what you are trying to achieve. I see from the first post you have rows and columns? Are you trying to arrange a grid of objects? Or arrange objects in a circular arc around a position?
Do you use MSN? This might be faster without the post delay.
#14
01/17/2005 (2:14 pm)
I've got AdiumX installed at home with MSN on that. Name there is dadaleous@hotmail.com.
#15
01/17/2005 (2:27 pm)
Cool. chris.r@paradise.net.nz. I'll be around for another half hour or so, then I'm off to lunch - back an hour or so after that.
#16
01/17/2005 (2:53 pm)
function getNodeTransform(%Node)
{
// get center of rotation
%p = $worldPositions.centerNode;
error("Rotation center = " @ " %p);
// get amount to rotate object (360/10 rows = 36 degrees per row)
%rotation = 36 * %Node.row;
%radianRotation = mDegToRad(%rotation);
error("Rotation angle = " @ %radianRotation);
// determine the objects initial position (use column)
%objTransform = %p SPC "1 0 0 0";
%x = getWord(%p, 0) + 5.3244 * %Node.column;
%objTransform = setWord(%objTransform, 0, %x);
error("Object initial transform = " @ %objTransform);
// do the rotation
%objectPosition = getWords(%objTransform, 0, 2);
%rot = %p SPC 0 SPC 0 SPC 1 SPC %radianRotation;
%start = VectorSub(%objectPosition, %p) SPC getWords($objTransform, 3, 6);
%nodeTransform = MatrixMultiply(%rot, %start);
error("Objects new transform = " @ %nodeTransform);
return %nodeTransform;
}
#17
01/17/2005 (3:29 pm)
At last, SUCCESS! I got it to work! THank you for all your help!!
#18
01/19/2005 (7:27 am)
Dave, I have one question. What type of object is %Node?
#19
01/19/2005 (2:44 pm)
StaticShape
Associate Dave Calabrese
Cerulean Games