Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411618 Posts in 69390 Topics- by 58447 Members - Latest Member: sinsofsven

May 10, 2024, 01:23:05 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Realistic turning (momentum)
Pages: [1]
Print
Author Topic: Realistic turning (momentum)  (Read 1924 times)
Mipe
Level 10
*****


Migrating to imagination.


View Profile
« on: November 28, 2009, 10:21:51 AM »

Okay, I have encountered a problem and it's been nagging me to the point where I pester you lot. I'd like to solve this in a simple and robust manner, since I'd be using it for a personal project later on.

Take an object, let's say a space ship, that we want to turn smoothly toward the desired direction (angle). Let us assume the mouse pointer to indicate desired direction. We want the ship to turn smoothly toward the mouse, accelerate and decelerate as necessary. (The ship uses thrusters to turn around with.) It is preferred not to overshoot the desired angle (otherwise the ship would keep turning left and right all the time).

How would you solve this problem in real time, when mouse can change position any time? Are there any expressions that would make me go "well, DUH!"?

How would YOU go about it?

Here is free beer for your trouble.  Beer!
Logged
Glaiel-Gamer
Guest
« Reply #1 on: November 28, 2009, 10:45:05 AM »

fake it!

Think of rotation and rotational velocity as a linear timeline


you want to go from 0 to X
you want 1st derivatives to be 0 at the endpoints and continuous

You want the 2nd derivatives to be either 1 or 0 or -1 (thrust on or thrust off, this can be tweaked if you aren't getting desirable results)

so the graph looks like this


|
|
|----o
|----•----o----t
|         •----
|
|
a


total velocity needs to be 0 by the end, so the first chunk and the last chunk need to be the same length [we'll call this a, and the middle chunk will be b]

total displacement needs to be θ

velocity will look like a trapezoid

area of that trapezoid will be:

1/2 a * a + [1/2 a * a] * b + 1/2 a * a = θ

= a*a+1/2a*a*b = θ
= a*a*(1+1/2*b) = θ

also remember

a + b + a = θ
2a+b = θ

solve for a and b (multiple solutions) and you're good.

2a+b = a*a+1/2*a*a*b
4a+2b=2a*a+a*a*b
4a-2a*a+a*a*b=2b
b = θ-2a

4a-(2a*a+a*a*(θ-2a)=2(θ-2a)
4a-2a*a-a*a*(θ-2a)-2*(θ-2a) = 0
4a-2a*a-θa*a+2a*a*a-2θ+4a = 0
2a^3 - [2+θ]a^2 + 8a - 2θ = 0
*wolfram alpha*



If i were you I'd fake it, and just do a = (θ - targetθ)/C, you might oscillate at the end a little but enough friction and you won't notice
« Last Edit: November 28, 2009, 10:53:53 AM by Glaiel-Gamer » Logged
Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #2 on: November 28, 2009, 11:05:43 AM »

Sounds like the kind of thing you could use a PID controller for. Somebody posted this link about it in the experimental technology thread.
Logged

Mipe
Level 10
*****


Migrating to imagination.


View Profile
« Reply #3 on: November 28, 2009, 11:49:38 AM »

Ugh... thanks for the headache.  Concerned I'll re-read in the morning when I'm more... attentionate.
Logged
st33d
Guest
« Reply #4 on: November 28, 2009, 12:27:46 PM »

In flash I use a linear interpolation thingy:

Code:
package com.robotacid.util.lerp {

/* interpolate between two angles using the value "t" as a multiplier (t is between 0 and 1) */
public function thetaLerp(a:Number, b:Number, t:Number):Number{
a += (Math.abs(b-a) > Math.PI) ? ((a < b) ? (Math.PI*2) : -(Math.PI*2)) : 0;
return a + (b-a) * t;
}

}

Obviously in Flash you need that in degrees, so here it is again:

Code:
package com.robotacid.util.lerp {

/* interpolate between two angles in degrees using the value "t" as a multiplier (t is between 0 and 1) */
public function degreeLerp(a:Number, b:Number, t:Number):Number{
a += (Math.abs(b-a) > 180) ? ((a < b) ? (360) : -(360)) : 0;
return a + (b-a) * t;
}

}

So you would enter into the function (current_value, target_value, rate_of_change)

And the function speeds towards the target value and then slows when near. It also accounts for the wrap-around that occurs with radians and degrees, which is a confusing issue in handling rotation equations.

Of course it's not going to settle on the exact angle, which is why the PID stuff is good reading, but unless you need an accurate angle, this method works fairly well and gives smooth results.
Logged
easynam
Level 5
*****



View Profile WWW
« Reply #5 on: November 28, 2009, 12:36:29 PM »

Is this by applying force to certain parts of a ship?

I dont know too much about this, but I think that if you set the rotational force to a multiple of:

Angle between ship and mouse + 5*change in angle between ship and mouse since last frame

Then it should work?

Angle between ship and mouse being this:


It works in gmod. Shrug
« Last Edit: November 28, 2009, 12:47:49 PM by easyname » Logged

Mipe
Level 10
*****


Migrating to imagination.


View Profile
« Reply #6 on: November 28, 2009, 12:53:45 PM »

Linear interpolation is simple, when you have initial and final values, however I'm talking real time adjustments here. Could try interpolating between frames, but that'd be a little ineffective.

Ugh... I need some sleep on this.
Logged
Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #7 on: November 28, 2009, 01:10:45 PM »

I'd use somthing simple like:

CurrentAngle = CurrentAngle + ((FinalAngle-CurrentAngle)/Speed)

This way you have fast turning at the begining and slower towards the end. It will never overshoot either due to the fact that it only increases by a fraction of the remaining angle, plus, due to the inaccuracies of floating point math it will actually reach the final angle instead of tending towards it.

Sounds like the kind of thing you could use a PID controller for. Somebody posted this link about it in the experimental technology thread.

This is kind of line pid controllers (I think) but very easy to understand. Its not very physically accurate, but it does the job and seems to work.

(BTW if my code is broken, tell me)
Logged
Mipe
Level 10
*****


Migrating to imagination.


View Profile
« Reply #8 on: November 28, 2009, 01:20:34 PM »

Doesn't account for acceleration, either.

I was kinda looking into cosine interpolation-like, but well, I guess that needs starting and ending point, which doesn't work too well in real-time, with the ship constantly steering left and right.

I may have to cheat and use variables, which store the momentum, however I'm not so sure how to calculate that into the angle adjustments. Momentum is easy, add a number each frame as long as the 'thruster' is firing.
Logged
Will Vale
Level 4
****



View Profile WWW
« Reply #9 on: November 29, 2009, 03:26:54 AM »

I'm pretty sure Brett (the AI coder) used the 'trapezium' technique for I-War 2, with some stuff to cope with the Newtonian mechanics, and it worked pretty well in the end but was tricky to get right. Certainly could be worth a try.

The damped controller/follower method is easier though, and you can cheat and catch overshoot by working out if your calculated frame's movement is going to take you past the target value or not and if so, snap to the target.
Logged
bateleur
Level 10
*****



View Profile
« Reply #10 on: November 29, 2009, 04:43:38 AM »

If you want simple, one hack I've quite often used is to only calculate the required acceleration (treating the ship as a point) and then for each frame set the angle to precisely match the angle of the ship's velocity vector at that instant.

This is completely wrong for any ship with a single thruster at the back, but looks weirdly convincing and is trivial to implement.
Logged

Tycho Brahe
Level 10
*****

λx.x


View Profile
« Reply #11 on: November 29, 2009, 04:47:30 AM »

I think the op is looking or a more asteroids like movement, rather than just faking the rotation. However i can't account for what he actually wants.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic