PDA

View Full Version : Finding required velocity for a object to reach from pt1(x,y,z) to p2(x,y,z)



acebuddy29
July 30th, 2009, 06:42 AM
Hi,
guys, can you help with this problem? how do i find the required initial velocity for an object to reach from 1 point to and 2nd point in 3D space. I have attached a really bad drawn image, just to make it clear. Hope it helps.

flyingmonkey456
July 30th, 2009, 08:05 AM
Hi,
guys, can you help with this problem? how do i find the required initial velocity for an object to reach from 1 point to and 2nd point in 3D space. I have attached a really bad drawn image, just to make it clear. Hope it helps.

this is kinda complex. first you would get the difference between x1 and x2, y1 and y2, and z1 and z2. make sure you keep these saved. you will now have to find the distance of the line. the formula is this:


sqrt( (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2) )

now you will have to divide each of the differences by the number you just got from that formula. those numbers are the x, y, and z increases required to move at one pixel per second along the given line. just multiply them by your speed and you're done.

i'm pretty sure i'm right on all of that, but i just pulled the whole thing out of my arse so i could be wrong :)

Sirisian
July 30th, 2009, 10:07 AM
sqrt( (x1-x2)^2 + (y1+y2)^2 + (z1-z2)^2) )


close, you just subtract each component.
length = sqrt( (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2) )
It's called vector normalization (http://en.wikipedia.org/wiki/Euclidean_vector#Unit_vector).


((x1-x2) / length, (y1-y2) / length, (z1-z2) / length)

flyingmonkey456
July 30th, 2009, 10:31 AM
close, you just subtract each component.
length = sqrt( (x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2) )
It's called vector normalization (http://en.wikipedia.org/wiki/Euclidean_vector#Unit_vector).


((x1-x2) / length, (y1-y2) / length, (z1-z2) / length)

typo, fixed now. thanks :)

acebuddy29
July 31st, 2009, 03:38 AM
I had already tried this but it didnt seem to work. let me check it again, i probably didnt do it right. i will post again after i test it. thanks guys.
-----------------------------------------------------------------------------------

damn it i got it why it didnt work last time. i didnt normalize the vectors on enterframe. so the object just kept on going on and on without stoping. Again thank you flyinmonkey and sirisian.

acebuddy29
July 31st, 2009, 06:17 AM
hey,
The object moves to the said point but it starts sort of wiggling once it reaches its destination. i know i can just stop the code at this point. But i want to know if this is a result of some mistake in the code. Am attaching the .fla its in cs4.

acebuddy29
August 1st, 2009, 02:28 AM
can somebody just check the fla and post some solution?

Gnoll
August 1st, 2009, 02:43 AM
Don't move it if dist is < your speed, I am assuming you are going beyond the point and then reversing etc.

Gnoll

Krilnon
August 1st, 2009, 03:29 AM
A cheap solution would look something like this when inserted into the code at the relevant line:
var len = Math.sqrt(diffx * diffx + diffy * diffy + diffz * diffz);

if(len < 100){
ball.x = target_x;
ball.y = target_y;
ball.z = target_z;
root.removeEventListener(Event.ENTER_FRAME, arguments.callee);
}

There are more analytic ways to do it that are more accurate; but this should be fine for your purposes, especially since it seems that you don't want to think about the code yourself. ;)

acebuddy29
August 1st, 2009, 03:38 AM
A cheap solution would look something like this when inserted into the code at the relevant line: ActionScript Code:

var len = Math.sqrt(diffx * diffx + diffy * diffy + diffz * diffz);

if(len < 100){
&nbsp;&nbsp;&nbsp;&nbsp;ball.x = target_x;
&nbsp;&nbsp;&nbsp;&nbsp;ball.y = target_y;
&nbsp;&nbsp;&nbsp;&nbsp;ball.z = target_z;
&nbsp;&nbsp;&nbsp;&nbsp;root.removeEventListener(Event.ENTER_FRAME , arguments.callee);
}




There are more analytic ways to do it that are more accurate; but this should be fine for your purposes, especially since it seems that you don't want to think about the code yourself. ;)

i know i could have done this, as i have mentioned it b4. But i just wanted to know if it was an error caused by me, maybe i was missing something important or something like that. thanks anyways.

flyingmonkey456
August 1st, 2009, 08:10 AM
you did the length formula wrong, i'll fix your fla and send it back to you. i'm also going to fix the jumping around when it gets to the target.

EDIT: alright, here it is. i can't get it to move any faster, if anybody else can please let me know how :)

TOdorus
August 1st, 2009, 10:46 AM
you did the length formula wrong, i'll fix your fla and send it back to you. i'm also going to fix the jumping around when it gets to the target.

EDIT: alright, here it is. i can't get it to move any faster, if anybody else can please let me know how :)

Just skimmed over it so I may be wrong here: shouldn't it be vector.x/y/z times length and not divided by length? Btw Math.pow is a lot slower then typing it out, so you would only want to use it when you need a variable power.

flyingmonkey456
August 1st, 2009, 11:13 AM
Just skimmed over it so I may be wrong here: shouldn't it be vector.x/y/z times length and not divided by length? Btw Math.pow is a lot slower then typing it out, so you would only want to use it when you need a variable power.

no, think of it like distance per length. you're finding the distance you have to go per 1 length, but you have a length of, say, 20 and you have to travel, say, 8 pixels on the y axis to reach the 20 length. if you divide both of them by 20, you would have 0.4/1 or 0.4 distance per 1 length. as for the power thing, thanks for the tip. could you solve the speed problem?

TOdorus
August 1st, 2009, 02:23 PM
What I always do is just normalize the vector to a unit vector (a vector with a length of 1) and then multiply it by the required speed. It still needs a check to stop when it has reached it's destination though, but I think acebuddy can easily manage that.



function baller (e:Event)
{
target_x = 400;
target_y = 400;
target_z = 300;
diffx = target_x - ball.x;
diffy = target_y - ball.y;
diffz = target_z - ball.z;
exctlen = Math.sqrt(Math.pow(diffx, 2) + Math.pow(diffy, 2) + Math.pow(diffz, 2));
//
rx = diffx / exctlen * speed;
ry = diffy / exctlen * speed;
rz = diffz / exctlen * speed;
ball.x += rx;
ball.y += ry;
ball.z += rz;
}


But really, to make life easy on yourself you should really create a 3D vector class. If you're a math fan like me (irony), then you should be glad to hear that the equations are all over the net.

flyingmonkey456
August 1st, 2009, 02:51 PM
What I always do is just normalize the vector to a unit vector (a vector with a length of 1) and then multiply it by the required speed. It still needs a check to stop when it has reached it's destination though, but I think acebuddy can easily manage that.



function baller (e:Event)
{
target_x = 400;
target_y = 400;
target_z = 300;
diffx = target_x - ball.x;
diffy = target_y - ball.y;
diffz = target_z - ball.z;
exctlen = Math.sqrt(Math.pow(diffx, 2) + Math.pow(diffy, 2) + Math.pow(diffz, 2));
//
rx = diffx / exctlen * speed;
ry = diffy / exctlen * speed;
rz = diffz / exctlen * speed;
ball.x += rx;
ball.y += ry;
ball.z += rz;
}


But really, to make life easy on yourself you should really create a 3D vector class. If you're a math fan like me (irony), then you should be glad to hear that the equations are all over the net.

ah, but creating a unit vector is exactly what i'm doing :) read the second post again, it explains it step by step. the equation in the code tags is the equation to get the length. when you find the difference between each coordinate of the end and start points, you get the distance you have to travel along each axis to reach the end of the vector in one frame. if you divide each of those distances by the length of the vector, you keep the same ratios and therefore the same direction, but at only one pixel per frame. then, like you said, just multiply by the speed.

TOdorus
August 1st, 2009, 03:06 PM
Yeah, I realised that when reading through your code, but then I ran into the following lines.


len = Math.round(exctlen / speed) * speed;
rx = diffx / len;
ry = diffy / len;
rz = diffz / len;


That's just so different to my usual method that I could make heads nor tails of it (I'm quite set in my ways). What really struck me as odd (and still does) is the "/ len" part. I can't see why it shouldn't be "* len" as that tells the vector how much bigger it needs to be.



len = speed/exctlen;
rx = diffx * len;
ry = diffy * len;
rz = diffz * len;


I like my method better as it really shows the vectormath better instead of using some abstract ratio as len. But hey, that's totally subjective.

flyingmonkey456
August 1st, 2009, 03:13 PM
I like my method better as it really shows the vectormath better instead of using some abstract ratio as len. But hey, that's totally subjective.

the way the code is written was all the op, i would have done it differently as well.

acebuddy29
August 4th, 2009, 08:52 AM
am stuck at figuring the following part out.


len = Math.round(exctlen / speed) * speed;

rx = diffx / len;
ry = diffy / len;
rz = diffz / len;

TOdorus
August 4th, 2009, 09:32 AM
am stuck at figuring the following part out.


len = Math.round(exctlen / speed) * speed;

rx = diffx / len;
ry = diffy / len;
rz = diffz / len;




Maybe if you'd read posts #2, #3, #14 and #15 for some explenation and posts #14 and/or #16 for some code?