Argh maths! Train problem...

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
edit:If you can think of any improvement to the questions, wording, versatility or whatever, please say so, :) thanks.

Right...I've got no idea if this is easy or hard, what level it is etc, I just know it's beyond me today; working with vectors and matrix multiplications has sploded my brain! So here it is. None of the specific numbers are known prior to use so I'm looking for generic equations to solve the three following problems. Fear not, this isn't a homework cheat or anything, they're my questions which I can't even answer.../sigh. If wanted I'll post the resulting code for anyone who wants it :):

Variables in their simplest form:

Current point.
Destination point.
Total Time of the journey.
Current Time of the journey.
Elapsed time since the last tick.

Worthy of note is that the current and destination points, as well as the total time of the journey may change at any point during cycling of the used equation. Once in transition, the object will be unaware of its source point of origin so use of this variable is not allowed. The equations calculated must be shown as an amendment of the previous test and as such, tests may be taken at any specific non-integer based unit of time elapsed, throughout the objects journey. Unit descriptors are insignificant.

1)Determine an accurate equation for use which will allow the object to travel from a source point to its destination in a linear fashion.

2)Determine an accurate equation for use which will allow for the object to travel and arrive at its destination as if under deceleration in an exponential fashion, using the equation of x squared.

3)Use the above equation to calculate deceleration with an unknown exponent.




1)My gut instinct was to try:

Amend position by : (Destination - Source) / (Total time - Current time).

The problem comes with time remaining being measured at irregular points. I'll demonstrate the problem.

___Distance remaining_____Time remaining___
_________20__________________5_________
_________16__________________4_________
_________12__________________3_________
__________8__________________2_________
__________4__________________1_________
__________0__________________0_________

So you apply the formula to the first instance which is a simple 20/5 = 4 and thus amend the position by 4. If the next tick is at 1 second in, you can take 16, divide it by 4 and the formula still works. If however the next tick is at any other time, it simply falls apart as it hasn't taken into consideration the amount of time elapsed since the last test.

So the answer is:

Amend position by : ((Destination - Source) / (Total time - Current time)) * elapsedTime.


2) Here is where I'm stuck. If the source point was always zero, it wouldn't be so much of a problem but it's not. Any ideas anyone? Thanks in advance, have fun! :D
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
For question number 2 (and 3 I guess), here is a demonstrative graph of what I mean.

timedistance.jpg
 

Bugz

Fledgling Freddie
Joined
May 18, 2004
Messages
7,297
Try thestudentroom to be honest - some of the uni students on there are absolutely fantastic with maths.
 

Chilly

Balls of steel
Joined
Dec 22, 2003
Messages
9,047
this is not uni level. this is 13 year old level...


/edit, except the hard bits I didnt bother to read :p
 

Chilly

Balls of steel
Joined
Dec 22, 2003
Messages
9,047
well for the deceleration you know that the speed is determined by x^n and you know how far you need to go to get to the end point. so you plug the distance into the time euation then differentiate for distance.

i cba to do the differentiation but that's basically it.
 

mycenae

Can't get enough of FH
Joined
Aug 22, 2005
Messages
877
if thats maths for 13yr olds, I'm in the shit when it comes to helping my kids with maths homework....I'm so glad Vae is good with numbers!
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
I've had another look and am partially there. I've figured out that quadratic equations are needed although not in the sense I know them.

If you have the end point on the graph, as well as the beginning and an exponent which can be manipulated to whatever you want it to be, does anyone have any pointers as to how to figure out any point on the graph (other then those two...? :)

totalTime - currentTime will give the beginning x value, totalTime - currentTime + elapsedTime will give the second x position.

ax^z + bx + c...

c is unrequired so ax^z +bx...

So what do you do if you don't know the quadratic and linear cooeficients, argh! Or do I already know them and I just don't know it yet (from the variables given in the top post)?


It's an as-level pure 1 issue but sadly I can't remember for the life of me how to do it. Any suggestions would be greatly appreciated. :) Could show the resulting video if wanted as an incentive!
 

Bugz

Fledgling Freddie
Joined
May 18, 2004
Messages
7,297
Without looking too closely at your equation, I would say to find a, b (& c), you'd be best formulating some simultaneous equations.

if x represents time, y represents distance. So you have y = ax^z + bx (+ c).

If you differentiate (dy/dx) you'll get a 2nd equation. Consider the points when dydx = 0.

You have values to plug in from your table & you can simply do some simple algebra to find the values of a & b.
 

Garaen

One of Freddy's beloved
Joined
Dec 27, 2003
Messages
985
Without looking too closely at your equation, I would say you're screwed tbh.
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
Well it's all implemented and working. Currently the camera begins slow and ends fast but that's a minor issue. The formula is also split into two parts to avoid double calculation of the same exponent value. As for part three, you merely replace the ^2 with ^t.

Formulae required:

y = ax^2 + bx + c.
AmendPositionBy : ((elapsedTime + currentTime) * a)^2 - (currentTime * a)^2


For anyone interested in the code, or if anyone could help improve the general calculation times somehow:

//Exponential movement is calculated using y=ax^2 + c.
//where a = (destinationPos - currentPos) / totalTime - currentTime);
// y = distance,
// c = starting distance,
// x = time.
//AmendValue parameter required for negative movement. Negative number squared would be positive which needs to be avoided in this instance.

//Modify the XPosition.
double graphExponent = (double)((lockPosition->getPlacementX() - currentPosition->getPlacementX()) / (pow(movementTime, 2) - pow(currentTime, 2)));
double amendValue = (pow((dManager->getElapsedTime() + currentTime) * graphExponent, 2) - pow(currentTime * graphExponent, 2));
if(graphExponent < 0)
currentPosition->amendPlacementX((float)-amendValue);
else
currentPosition->amendPlacementX((float)amendValue);



Repeat the final 7 lines for Y and Z rotations.

I'll post the rotational calculations once they're in and working.
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
Lot of ADHD potential in this thread :D

/hug.

Forgot to post the code. Currently I've only got it working for the camera beginning slow and speeding up as it closes in on the object but anyway, anyone interested in the code, here it is. It all works except for rotation on the z-axis which is highly frustrating. It's not working for linear or exponential movement however so that leads me to beleive that the problem is rooted elsewhere, probably with my matrix manipualtions.

edit:Argh at removal of trailing spaces and tabs!
//If the camera is in transition between its old camera position and the new one.
if(moving == true){

//Transition confirmation.
if(currentTime <= movementTime){

//Linear positional movement.
if(cameraMovementType == CAMERA_TRANS_LINEAR){

//Determine the movement timer.
currentTime += dManager->getElapsedTime();

//Amend all placements using the same formulae.
currentPosition->amendPlacementX((float)(((lockPosition->getPlacementX() - currentPosition->getPlacementX()) / (movementTime - currentTime)) * dManager->getElapsedTime()));
currentPosition->amendPlacementY((float)(((lockPosition->getPlacementY() - currentPosition->getPlacementY()) / (movementTime - currentTime)) * dManager->getElapsedTime()));
currentPosition->amendPlacementZ((float)(((lockPosition->getPlacementZ() - currentPosition->getPlacementZ()) / (movementTime - currentTime)) * dManager->getElapsedTime()));

//Remove the elapsedTime count from the currentTime as we are at this point, unsure of how the timer is to be used in the rotational calculations.
currentTime -= dManager->getElapsedTime();
}

//else if negative exponent used for positional movement.
else if(cameraMovementType == CAMERA_TRANS_NEG_EXPONENT){

//Exponential movement is calculated using y=ax^2 + c.
//where a = (destinationPos - currentPos) / totalTime - currentTime);
// y = distance,
// c = starting distance,
// x = time.
//AmendValue parameter required for negative movement. Negative number squared would be positive which needs to be avoided in this instance.

//Modify the XPosition.
double graphExponent = (double)((lockPosition->getPlacementX() - currentPosition->getPlacementX()) / (pow(movementTime, 2) - pow(currentTime, 2)));
double amendValue = (pow((dManager->getElapsedTime() + currentTime) * graphExponent, 2) - pow(currentTime * graphExponent, 2));
if(graphExponent < 0)
currentPosition->amendPlacementX((float)-amendValue);
else
currentPosition->amendPlacementX((float)amendValue);

//Modify the YPosition.
graphExponent = (double)((lockPosition->getPlacementY() - currentPosition->getPlacementY()) / (pow(movementTime, 2) - pow(currentTime, 2)));
amendValue = (pow((dManager->getElapsedTime() + currentTime) * graphExponent, 2) - pow(currentTime * graphExponent, 2));
if(graphExponent < 0)
currentPosition->amendPlacementY((float)-amendValue);
else
currentPosition->amendPlacementY((float)amendValue);

//Modify the ZPosition.
graphExponent = (double)((lockPosition->getPlacementZ() - currentPosition->getPlacementZ()) / (pow(movementTime, 2) - pow(currentTime, 2)));
amendValue = (pow((dManager->getElapsedTime() + currentTime) * graphExponent, 2) - pow(currentTime * graphExponent, 2));
if(graphExponent < 0)
currentPosition->amendPlacementZ((float)-amendValue);
else
currentPosition->amendPlacementZ((float)amendValue);
}

//else positive exponent used for positional movement.
else{

}

//Linear rotational movement.
if(cameraRotationType == CAMERA_TRANS_LINEAR){

//Determine the movement timer.
currentTime += dManager->getElapsedTime();

//Amend all rotations using the same formulae.
//Modify the XRotation.
//If the difference is greater then PI, work with minus 2PI.
if(lockPosition->getRotationX() - currentPosition->getRotationX() > D3DX_PI)
currentPosition->amendRotationX((float)(((lockPosition->getRotationX() - currentPosition->getRotationX() - (D3DX_PI * 2)) / (movementTime - currentTime)) * dManager->getElapsedTime()));

//else if the difference is less then minus PI, work with plus 2PI.
else if(lockPosition->getRotationX() - currentPosition->getRotationX() < -D3DX_PI)
currentPosition->amendRotationX((float)(((lockPosition->getRotationX() - currentPosition->getRotationX() + (D3DX_PI * 2)) / (movementTime - currentTime)) * dManager->getElapsedTime()));

//else, work with a standard rotation.
else
currentPosition->amendRotationX((float)(((lockPosition->getRotationX() - currentPosition->getRotationX()) / (movementTime - currentTime)) * dManager->getElapsedTime()));


//Modify the YRotation.
//If the difference is greater then PI, work with minus 2PI.
if(lockPosition->getRotationY() - currentPosition->getRotationY() > D3DX_PI)
currentPosition->amendRotationY((float)(((lockPosition->getRotationY() - currentPosition->getRotationY() - (D3DX_PI * 2)) / (movementTime - currentTime)) * dManager->getElapsedTime()));

//else if the difference is less then minus PI, work with plus 2PI.
else if(lockPosition->getRotationY() - currentPosition->getRotationY() < -D3DX_PI)
currentPosition->amendRotationY((float)(((lockPosition->getRotationY() - currentPosition->getRotationY() + (D3DX_PI * 2)) / (movementTime - currentTime)) * dManager->getElapsedTime()));

//else, work with a standard rotation.
else
currentPosition->amendRotationY((float)(((lockPosition->getRotationY() - currentPosition->getRotationY()) / (movementTime - currentTime)) * dManager->getElapsedTime()));


//Modify the ZRotation.
//If the difference is greater then PI, work with minus 2PI.
if(lockPosition->getRotationZ() - currentPosition->getRotationZ() > D3DX_PI)
currentPosition->amendRotationZ((float)(((lockPosition->getRotationZ() - currentPosition->getRotationZ() - (D3DX_PI * 2)) / (movementTime - currentTime)) * dManager->getElapsedTime()));

//else if the difference is less then minus PI, work with plus 2PI.
else if(lockPosition->getRotationZ() - currentPosition->getRotationZ() < -D3DX_PI)
currentPosition->amendRotationZ((float)(((lockPosition->getRotationZ() - currentPosition->getRotationZ() + (D3DX_PI * 2)) / (movementTime - currentTime)) * dManager->getElapsedTime()));

//else, work with a standard rotation.
else
currentPosition->amendRotationZ((float)(((lockPosition->getRotationZ() - currentPosition->getRotationZ()) / (movementTime - currentTime)) * dManager->getElapsedTime()));
}

//else if negative exponent used for rotational movement.
else if(cameraRotationType == CAMERA_TRANS_NEG_EXPONENT){

//Addressed for each of the 3 axis.
double graphExponent = 0;
double amendValue = 0;

//Exponential movement is calculated using y=ax^2 + c.
//where a = (destinationPos - currentPos) / totalTime - currentTime);
// y = distance,
// c = starting distance,
// x = time.
//AmendValue parameter required for negative movement. Negative number squared would be positive which needs to be avoided in this instance.

//Rotational positions based on a range of zero to 2*D3DX_PI.
//Modify the XRotation.
//If the difference is greater then PI, work with minus 2PI.
if(lockPosition->getRotationX() - currentPosition->getRotationX() > D3DX_PI)
graphExponent = (double)((lockPosition->getRotationX() - currentPosition->getRotationX() - (D3DX_PI * 2)) / (pow(movementTime, 2) - pow(currentTime, 2)));

//else if the difference is less then minus PI, work with plus 2PI.
else if(lockPosition->getRotationX() - currentPosition->getRotationX() < -D3DX_PI)
graphExponent = (double)((lockPosition->getRotationX() - currentPosition->getRotationX() + (D3DX_PI * 2)) / (pow(movementTime, 2) - pow(currentTime, 2)));

//else, work with a standard rotation.
else
graphExponent = (double)((lockPosition->getRotationX() - currentPosition->getRotationX()) / (pow(movementTime, 2) - pow(currentTime, 2)));

//Amend the rotational value in accordance with the graphExponent.
amendValue = (pow((dManager->getElapsedTime() + currentTime) * graphExponent, 2) - pow(currentTime * graphExponent, 2));
if(graphExponent < 0)
currentPosition->amendRotationX((float)-amendValue);
else
currentPosition->amendRotationX((float)amendValue);


//Modify the YRotation.
//If the difference is greater then PI, work with minus 2PI.
if(lockPosition->getRotationY() - currentPosition->getRotationY() > D3DX_PI)
graphExponent = (double)((lockPosition->getRotationY() - currentPosition->getRotationY() - (D3DX_PI * 2)) / (pow(movementTime, 2) - pow(currentTime, 2)));

//else if the difference is less then minus PI, work with plus 2PI.
else if(lockPosition->getRotationY() - currentPosition->getRotationY() < -D3DX_PI)
graphExponent = (double)((lockPosition->getRotationY() - currentPosition->getRotationY() + (D3DX_PI * 2)) / (pow(movementTime, 2) - pow(currentTime, 2)));

//else, work with a standard rotation.
else
graphExponent = (double)((lockPosition->getRotationY() - currentPosition->getRotationY()) / (pow(movementTime, 2) - pow(currentTime, 2)));

//Amend the rotational value in accordance with the graphExponent.
amendValue = (pow((dManager->getElapsedTime() + currentTime) * graphExponent, 2) - pow(currentTime * graphExponent, 2));
if(graphExponent < 0)
currentPosition->amendRotationY((float)-amendValue);
else
currentPosition->amendRotationY((float)amendValue);


//Modify the XRotation.
//If the difference is greater then PI, work with minus 2PI.
if(lockPosition->getRotationZ() - currentPosition->getRotationZ() > D3DX_PI)
graphExponent = (double)((lockPosition->getRotationZ() - currentPosition->getRotationZ() - (D3DX_PI * 2)) / (pow(movementTime, 2) - pow(currentTime, 2)));

//else if the difference is less then minus PI, work with plus 2PI.
else if(lockPosition->getRotationZ() - currentPosition->getRotationZ() < -D3DX_PI)
graphExponent = (double)((lockPosition->getRotationZ() - currentPosition->getRotationZ() + (D3DX_PI * 2)) / (pow(movementTime, 2) - pow(currentTime, 2)));

//else, work with a standard rotation.
else
graphExponent = (double)((lockPosition->getRotationZ() - currentPosition->getRotationZ()) / (pow(movementTime, 2) - pow(currentTime, 2)));

//Amend the rotational value in accordance with the graphExponent.
amendValue = (pow((dManager->getElapsedTime() + currentTime) * graphExponent, 2) - pow(currentTime * graphExponent, 2));
if(graphExponent < 0)
currentPosition->amendRotationZ((float)-amendValue);
else
currentPosition->amendRotationZ((float)amendValue);

//Determine the movement timer for the next 'tick'.
currentTime += dManager->getElapsedTime();
}

//else positive exponent used for rotational movement.
else{

//Determine the movement timer for the next 'tick'.
currentTime += dManager->getElapsedTime();
}
}

//The camera has reached its destination.
else{

//The camera is set to no longer move between positions.
moving = false;

//Firstly, remove the transitional positions object.
delete currentPosition;
currentPosition = NULL;

//Lock the camera to the new associated object.
currentPosition = lockPosition;
}
}

And anyone who can see efficiency improvement, feel free to comment, otherwise I guess this thread has run its course! :)
 

Bahumat

FH is my second home
Joined
Jun 22, 2004
Messages
16,788
From what I can see, X^n /4H = L-LP
But then again I dont know what i am talking about and made this up
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
Is this for a speed camera or some such device?

Almost. :)

It's for a camera system itself. CurrentPosition is the literal world position of the camera, lockPosition is its target. The timer is there for movement between two objects.

With the calculation worked out, it'll be a much easier task to use exponential movement for all objects in the world.

From what I can see, X^n /4H = L-LP
But then again I dont know what i am talking about and made this up

All depends on what H/L and LP stand for...
 

Ch3tan

I aer teh win!!
Joined
Dec 22, 2003
Messages
27,318
Well if it's a, you know, lion out of the closet, then he ain't going to do shit.
 

Fweddy

FH is my second home
Joined
Dec 22, 2003
Messages
1,304
You ever tried to take a lollipop away from a lion? Hells bells! ;) ;)

It's not that difficult. As long as you're keen enough that you can honestly say to yourself "I'd give my right arm for that lollipop" then you're in with a good chance.
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
Have got another silly problem come up for the final part of the camera system... I'll cut to the chase anyway.



How do I map this graph as an equation? I know there's a simple answer, making sin linear or thereabouts but I can't for the life of me figure this out. I can do it for a single turn in the equation like so:

y = sqrt((x - 3)^2);

That of course will only work for 1-4 however. Any ideas or pointers anyone?
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
Nevermind, I just found the answer...

Square the values of sin basically and you're there. Well I learnt something new today, sin/cos actually make more mathematical sense to me now, lol.
 

kirennia

Part of the furniture
Joined
Dec 26, 2003
Messages
3,857
Nevermind, I just found the answer...

Square the values of sin basically and you're there. Well I learnt something new today, sin/cos actually make more mathematical sense to me now, lol.

Wrong, wrong, wrong... /sigh. Should have know it was wrong really and need to stop going off and doing other things instead of this. :p
 

Users who are viewing this thread

Top Bottom