• Advertisement
Sign in to follow this  

Moving an Object in 3D

This topic is 4427 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 know this probably has been asked before, but every time I search for it, I can't seem to find what I'm looking for, and if I have found it, then I really don't understand it. I want to be able to move an object in 3D, say with a resultant of 100. But if I rotate the object around on the x and y axis, I don't know how to find the new coordinates. I've looked around on the internet, and I often see all this Matrix transormation stuff and rotations, but I'm not sure exactly how to do it, the tutorials are confusing and I'm not sure it does what I want it to. Anyways, all I'm really looking for is a clear explanation. --Thanks, Michael

Share this post


Link to post
Share on other sites
Advertisement
matrices are what you need. with a matrix you can describe the translation, rotation, scale etc of an object.

check out "mathematics for 3d game programming & computer graphics 2nd ed." :
<http://www.amazon.com/gp/product/1584502770/qid=1136436369/sr=8-1/ref=sr_8_xs_ap_i1_xgl14/104-0176799-2308757?n=507846&s=books&v=glance>

also "the cg tutorial" covers the basics of this stuff, and you could learn shaders while you're at it:

<http://www.amazon.com/gp/product/0321194969/qid=1136436540/sr=2-1/ref=pd_bbs_b_2_1/104-0176799-2308757?s=books&v=glance&n=283155>

Share this post


Link to post
Share on other sites
The short of it is that you are looking for a Translation matrix, which is a type of transform.

In your game or program, keep track of an objects position any way you like, I personally use a 3D vector to do so. If your object moves in the positive X direction by 100 units, simply add 100 to the x value of the vector.

Now when you are creating the visual representation of your object, (be it a quad, mesh, sphere etc.) make sure it is centered around the origin. Now when you go to draw it on the screen, simply set the world transfrom equal to a translation matrix based off of your objects position. How this is actually done will depend on the API you are using. Could you let us know if you are using directx or opengl?

Share this post


Link to post
Share on other sites


glBegin(GL_TRIANGLES);

glRotatef(rx, ry, rz);
glTranslatef(tx, ty, tz);

glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(-2.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 2.0f, 0.0f);

glEnd();



This code just draws a triangle that is rotated by 'rx' on the x-axis, 'ry' on the y-axis and 'rz' on the z-axis. It is also translated (moved) by 'tx' on the x-axis, 'ty' on the y-axis and 'tz' on the z-axis.

Share this post


Link to post
Share on other sites


glBegin(GL_TRIANGLES);

glRotatef(rx, 1.0f, 0.0f, 0.0f);
glRotatef(ry, 0.0f, 1.0f, 0.0f);
glRotatef(rz, 0.0f, 0.0f, 1.0f);

glTranslatef(tx, ty, tz);

glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(-2.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 2.0f, 0.0f);

glEnd();



This code just draws a triangle that is rotated by 'rx' on the x-axis, 'ry' on the y-axis and 'rz' on the z-axis. It is also translated (moved) by 'tx' on the x-axis, 'ty' on the y-axis and 'tz' on the z-axis.

Everything happens behind the scenes of those function calls.
The glRotatef function will multiply the modelview matrix by rotation matrices it constructs. And the glTranslatef function does the same thing, but with translation matrices.

Share this post


Link to post
Share on other sites
Quote:
But if I rotate the object around on the x and y axis, I don't know how to find the new coordinates


I'm a little confused. If you apply a rotation matrix to a point (multiply), what you get are the new coordinates.

Share this post


Link to post
Share on other sites
Quote:
Original post by MikeTacular
c++ and OpenGL, sorry about that


If you haven't done so already, take a look at the NeHE OpenGL tutorials. They've helped many a beginner get started with 3D graphics.

Share this post


Link to post
Share on other sites
I think i know what your problem is, you want camera relative movement, right?

newz += speed*cos(rotation)
newx += speed*sin(rotation)

This formula is for the "forward" button, I think you can figure out the others yourself.

I think rotation has to be in radians.
radians = degrees*(pi/180)

Share this post


Link to post
Share on other sites
Well....actually I think I may have poorly explained the first time. noteventime was close, except I already know how to do it for 2D, I just need to do it with 3D. The problem with glTranslate(tx,ty,tz) is that I don't know tx, ty, or tz. Let me try to do a little example.


A,B,C are sides
a,b,c are angles

/|
/b| A=80
/ | B=60
C / | A C=100
/ |
/ | a=53.13 degrees
/ | b=36.87
/a_____c| c=90
B









I can do it in 2D as you see, but my problem is 3D.

I don't know how to find the new coorodinates (X,Y,Z). I've looked a lot at matrices, but the major problem is that it has a matrix for translating along certain values, with a matrix of
[ 1,  0,  0, 0]
[ 0, 1, 0, 0]
[ 0, 0, 1, 0]
[tx, ty, tz, 1]

But I don't know how to find tx, ty, or tz.

Another way of saying this, is that I want a function called move(float distance). I want that function to change the object's (or camera's) cooridanites depending on how far I want it moved and its rotation. I want it to move the way its facing.

Thanks for the replies, but none have answered my question yet.

Share this post


Link to post
Share on other sites
so do you want to move the object in the direction that it is faceing?

edit:
oh well you clearly said that you want it to move in the direction it is faceing.

so you want a function like this:

void move(float dist);

can't do it, you would need a direction. think about it, what would you do if i told you to move an object 33ft? you'd probably ask which direction i wanted you to move in. you'd need something more like this:

matrix4x4 move(float dist, vector3 dir)//dir should be a unit vector
{
dir*=dist;
matrix4x4 T = MatrixIdentity(T);
T._41 = dist.x;
T._42 = dist.y;
T._43 = dist.z;
return T;
}

or, even better:

matrix4x4 move(vector3 dir)//dir does NOT need to be a unit vector
{
matrix4x4 T = MatrixIdentity(T);
T._41 = dist.x;
T._42 = dist.y;
T._43 = dist.z;
return T;
}

either of those would translate some object however you specified.

note: consider the above fonctions psudocode.

Share this post


Link to post
Share on other sites
that doesnt work. If i did this:

X,Y,Z are coordinates
xa,ya are angles
dist = distance i want to move

X=sin(ya)*dist
Y=sin(xa)*dist
Z=cos(ya)*dist

Lets say I was in coordinates (0,0,0), xa was 45 degrees, and ya was 30, and I wanted to move 100 units. If I plug that in I get:

X=50 units
Y=70.71 units
Z=86.60 units

But that's not moving 100 units. That would be 122.47 units.

[edit]

I didn't see your update minamur, sorry. I see what you mean, but the problem is that I don't know how far I want to move along each axis. I want a resultant (or hypotonuse if you will) to equal 100. I'd already have the objects angles stored, so my function doesn't need to have them put in it (although I don't mind for purposes of examples and what not). All I know is how far I want to move (in total movement, not along each axis), and what angles to move at. What I need to figure out is dist.x, dist.y, and dist.z, (the distance I want to move along each axis to produce a total movement of 100), but I don't know how too.

Share this post


Link to post
Share on other sites
First calculate the three factors without multiplying them.
eg:
fx: sin(phetaXZ) = 0.7
fy: sin(phetaYZ) = 0.5
fz: cos(phetaXZ) = 0.3

then the final result is:
x=speed*(fx/(x+y+z))
y=speed*(fy/(x+y+z))
z=speed*(fz/(x+y+z))

Then just add these to your x, y and z coordinates :D, enjoy!

Hope this is right, It's just an idea i got... havn't tried and theres probably something wrong.

Share this post


Link to post
Share on other sites
Imagine that you've got a vector coming from the center of the object which represents its "look direction." When the object is entirely unrotated, this vector is (0,0,1) in world space - pointing straight down the Z axis. So the object, in its 'rest position,' points down the Z axis.

Now say that you apply a couple of rotations to the object. You'd apply these to the look direction vector too; say you end up with the vector (0.2, 0.5, 0.7) (though in reality you'd normalise it).

Now you want to move 10 units in that direction: It's as simple as "position += 10 * lookDirection". You add 10*0.2=2 to the X, 10*0.5=5 to the Y, and 10*0.7=7 to the Z.

The matrix math you've been seeing is basically a shorter form of this.

Share this post


Link to post
Share on other sites
noteventime: it doesn't work, although it was a good idea. also, it wouldn't work if the player was at (0,0,0), since you can't divide by 0.

superbig: that doesn't work either. if you use the distance formula (in this case it would be sqrt(4+25+49)) you don't get 10 units, you get 8.83176. Thanks though


Please people, I have no idea how to do this, and I'm willing to hear whatever you've got. Thanks for all the replies I've had so far though.

Share this post


Link to post
Share on other sites
Good news everyone. I've almost got it. I was sitting there, looking at all this junk and formulas and triangles and everything, when suddenly I got a great idea. What came to me was something similar to what noteventime said, but a little different. Here is the code.


#include <iostream>
#include <math.h>

#define pi 3.14159265358979323846264338327950288419716939937510582097494459230781640628620
//note: I know pi is already defined.....but this is what boredom leads too....
//and no I didn't figure it out, its from a website that has pi up to 1 million places.

using namespace std;

struct ANGLE {
float x,y,z;
};

struct OBJECT {
float x,y,z;
ANGLE angle;
};

OBJECT obj;

float dist; //variable to state how far you want to move

ANGLE temp; //thing for manipulating stuff

float t; //used for the ratio, very important

int main()
{
cout << "Enter Object's Angles" << endl;
cout << "X: ";
cin >> obj.angle.x;
cout << "Y: ";
cin >> obj.angle.y;

obj.angle.x *= pi/180;
obj.angle.y *= pi/180;

cout << endl << endl;

cout << "Enter Object's Current Position" << endl;
cout << "X: ";
cin >> obj.x;
cout << "Y: ";
cin >> obj.y;
cout << "Z: ";
cin >> obj.z;

cout << endl << endl;

cout << "Enter Move Distance: ";
cin >> dist;
cout << (temp.x = sin(obj.angle.y)*dist) << endl;
cout << (temp.y = sin(obj.angle.x)*dist) << endl;
cout << (temp.z = cos(obj.angle.y)*dist) << endl;

//this is where the magin happens. I find the ratio its at, and that way
//I scale the movement so it is proper, otherwise, I would move to far/short
t = dist / sqrt(temp.x*temp.x + temp.y*temp.y + temp.z*temp.z);

temp.x *= t;
temp.y *= t;
temp.z *= t;

obj.x += temp.x;
obj.y += temp.y;
obj.z += temp.z;

cout << endl << "Object's Position" << endl << "X: " << obj.x << endl <<"Y: " << obj.y << endl << "Z: " << obj.z << endl;

cout << "Total Move Distance: " << sqrt(temp.x*temp.x + temp.y*temp.y + temp.z*temp.z) << endl;

getchar();
getchar();
}






Now I do have one problem though. If I angle it on the x axis, then I still move an improper amount on the z axis. I'm not sure if I just have to do a little
if (obj.angle.x == 90 || obj.angle.x == 270) temp.z = 0;


I still have to test it, and it probably needs a few revisions to make it more accurate and faster, but if you have any comments that would be great.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement