• Advertisement
Sign in to follow this  

Friction

This topic is 4429 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 the formula and all to pull it off, and how to get the Normal force and all, but after trying it out in an example app, I failed miserably. Can anyone show me some example code on an object sliding along a surface till it gets slower and slower, and makes a complete stop? Thanks.

Share this post


Link to post
Share on other sites
Advertisement
Yeah, here's my code. It's in VB, but you should be able to understand it easily. I'm only showing you the math stuff I used though, not the whole project.



'-------------------------------------------
'Variables I declared
'-------------------------------------------

Private Const GRAVITY As Single = 9.8

Private X As Single, Y As Single 'X and Y position
Private x0 As Single, y0 As Single 'Initial position
Private t As Single 'Time
Private v As Single 'Velocity
Private m As Single 'Mass
Private v0 As Single 'Initial Velocity
Private F As Single 'Net Force
Private N As Single 'Normal Force
Private u As Single 'Dynamic Friction Coefficient
Private Fric As Single 'Friction Force

'-------------------------------------------
'Math functions
'-------------------------------------------
Private Function Normal_Force(m As Single, g As Single) As Single

Normal_Force = m * g

End Function

Private Function Net_Force(m As Single, a As Single) As Single

Net_Force = m * a

End Function

Private Function Friction_Force(u As Single, N As Single) As Single

Friction_Force = u * N

End Function

'-------------------------------------------
'Initialized values when the program loads
'-------------------------------------------

Private Sub Form_Activate()

X = 100
Y = 200
x0 = X
y0 = Y
m = 68
u = 0.3
F = Net_Force(m, 1)
N = Normal_Force(m, GRAVITY)
Fric = Friction_Force(u, N)
v0 = F / m

Milliseconds = Get_Elapsed_Seconds

End Sub

'-------------------------------------------
'Main loop
'-------------------------------------------

Private Sub Game_Loop()

Do While Running = True

DoEvents

Lock_FPS 60

t = Get_Elapsed_Seconds - Milliseconds

v = v0 * F * t

X = x0 + v

PSet (X, Y), RGB(0, 0, 0)

Loop

End Sub





[Edited by - Jacob Roman on January 4, 2006 8:45:34 PM]

Share this post


Link to post
Share on other sites
I didn't implement friction in my code cause I couldn't do it. I just have an object moving consistantly towards the right at the same speed. So if any of you math geniuses know how to pull this off, I would sure appreciate it.

Share this post


Link to post
Share on other sites
I didn't go through the whole code but ... instead of these 2 lines here:

Quote:
v = F * t

X = x0 + v


Do something like

v += F * t
X = x0 + v*t


I didn't get what languuage that was--if the '+=' is not allowed, change it as you see fit.

Remember, if there is no force acting, there chould be no change in velocity. In the above lines, if 'F' is 0, then X gets changed by an unoform amount (with a stable frame rate), wehich is what you want. When you have frictional force (make sure this is negative so that the object slows) the velocity decreases like you would expect.

NOTE:

1. Make sure you have something in there to stop the object if it's velocity is 0, or else it will start going backwards.

2. If you read the FAQ, you will see that Euler integration is evil and you shouldn't use it. Think of a replacement long-term.

Share this post


Link to post
Share on other sites
I originally had it like that but the problem was that it made it go from 0 to 60 mph (metaphorically speaking) and left the window.

Just so you know, my variable t (time) is in milliseconds, so 0.001 would be 1 millisecond, and 1.000 would be 1 second. It's not time per frame, cause if it was, it would make it move consistantly then. ;)

[EDIT] Nevermind, I stuck v0 (initial velocity) in there for v = v0 + F * t, but had to make X = x0 + v cause it looked very awkward multiplying t in there as well. I already done it with v, so it wasn't needed in the other one.

Share this post


Link to post
Share on other sites
Quote:
Original post by deavik
2. If you read the FAQ, you will see that Euler integration is evil and you shouldn't use it. Think of a replacement long-term.


hopefully i'm not starting a whole big thing, but why is it evil. it doesn't say in the faq.

just to try and NOT hijack this thread, is it because of the (relatively) large error it intorduces for large timesteps?

Share this post


Link to post
Share on other sites
Quote:
Original post by minamur
Quote:
Original post by deavik
2. If you read the FAQ, you will see that Euler integration is evil and you shouldn't use it. Think of a replacement long-term.


hopefully i'm not starting a whole big thing, but why is it evil. it doesn't say in the faq.

just to try and NOT hijack this thread, is it because of the (relatively) large error it intorduces for large timesteps?


If by "relatively large" you mean "the potential for all your variables to shoot off to infinity and then some" then you would be correct.

Share this post


Link to post
Share on other sites
Another thing is

v = v0 * F * t
X = x0 + v

Should be

v = v0 + F * t / m
X = x0 + v * t

And including friction,

v = v0 + (F - Fric) * t / m

Share this post


Link to post
Share on other sites
Well like I said earlier, these formulas didn't work right:

v = v0 * F * t
X = x0 + v * t

And the reason is cause time has already been multiplied. So if you do this:

X = x0 + v0 * F * t

Then you'll see what I mean. Multiplying t to both equations made it go from slow to fast, when it was suppose to be constant speed.

Also, this didn't decelerate at all.

v = v0 + (F - Fric) * t / m

It maintained constant speed. Not sure what I need to do though.

Share this post


Link to post
Share on other sites
in 2D, to simplify...

euler on a particle

acc = SumF / mass
vel += acc * dt
pos += vel * dt + acc * 0.5 * (dt*dt)

taking into account angular momentums

ang_acc = SumT / inertia
ang_vel += ang_acc * dt
ang_pos += ang_vel * dt

To find SumF and SumT, when you add a force to the system

force if of vector F, and applied at point P on the body

SumF += F
SumT += (P - CG) ^ F

Suppose you have a sphere, rolling down an incline, and under the effect of gravity.



if you refer to chris hecker's phyiscs, you'll get the equations and principles of rigid body dynamics. as for some code, you can check this little demo.

Share this post


Link to post
Share on other sites
v = v0 * F * t
X = x0 + v * t

Quote:

And the reason is cause time has already been multiplied. So if you do this:

X = x0 + v0 * F * t


v should be v0 + F*t/m;
That should make
X = x0 + (v0 + F*t/m)*t;
= x0 + v0*t + F*t*t/m

Which is what is should be. I know that time is already multiplied in, but it should be in there twice for the (F/m) term. The general equation is:
x = x0 + v0t + at2

Quote:

v = v0 + (F - Fric) * t / m


If you make the suggested revisions, then you can calculate the time required to stop your object:

v = m*1/m + (m*1 - m*g*u)*t/m
0 = 1 + (1-g*u) *t
t = -1/-1.94
t = 0.52

Share this post


Link to post
Share on other sites
As an additional thought, the friction force resists motion, and it should be 0 if there are no other forces present. Is it possible that your object is stopping in half a second, but then is incorrectly being propelled by your friction force? Using the snippet you posted, it seems possible.

Share this post


Link to post
Share on other sites
Wow! Much better feedback. I'll give it a whirl when I get home. If I still have problems after updating it, then in my next post, I'll post the whole code, and see if you guys can fix it.

Share this post


Link to post
Share on other sites
I think I just got it! The problem was that I didn't need F. I already had a force going through Normal Force. Here's my code:


Option Explicit

Private Declare Function QueryPerformanceCounter Lib "Kernel32" (lpPerformanceCount As Currency) As Long
Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (lpPerformanceCount As Currency) As Long

Private Const GRAVITY As Single = 9.80665
Private Const POUNDS_TO_KILOGRAMS As Single = 0.45359237

Private Running As Boolean

Private Time As Single
Private Milliseconds As Single
Private Ticks_Per_Second As Currency
Private Start_Time As Currency

Private Flag As Boolean

Private X As Single, Y As Single 'X and Y position
Private x0 As Single, y0 As Single 'Initial position
Private t As Single 'Time
Private v As Single 'Velocity
Private m As Single 'Mass
Private v0 As Single 'Initial Velocity
Private F As Single 'Net Force
Private N As Single 'Normal Force
Private u As Single 'Dynamic Friction Coefficient
Private Fric As Single 'Friction Force

Private Function Hi_Res_Timer_Initialize() As Boolean

If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then

Hi_Res_Timer_Initialize = False

Else

QueryPerformanceCounter Start_Time
Hi_Res_Timer_Initialize = True

End If

End Function

Private Function Get_Elapsed_Seconds() As Single

Dim Last_Time As Currency
Dim Current_Time As Currency

QueryPerformanceCounter Current_Time
Get_Elapsed_Seconds = (Current_Time - Last_Time) / Ticks_Per_Second
QueryPerformanceCounter Last_Time

End Function

Private Function Lock_FPS(ByVal Target_FPS As Byte) As Single

If Target_FPS = 0 Then Target_FPS = 1

Static Last_Time As Currency
Dim Current_Time As Currency
Dim FPS As Single

Do

QueryPerformanceCounter Current_Time
FPS = Ticks_Per_Second / (Current_Time - Last_Time)

Loop While (FPS > Target_FPS)

QueryPerformanceCounter Last_Time

End Function

Private Function Normal_Force(m As Single, g As Single) As Single

Normal_Force = m * g

End Function

Private Function Net_Force(m As Single, a As Single) As Single

Net_Force = m * a

End Function

Private Function Friction_Force(u As Single, N As Single) As Single

Friction_Force = u * N

End Function

Public Sub Main()

With frmmain

.Caption = "Press Space"
.ScaleMode = 3
.AutoRedraw = True
.DrawWidth = 10

End With

X = 50
Y = 200
x0 = X
y0 = Y
m = 150 * POUNDS_TO_KILOGRAMS
N = Normal_Force(m, GRAVITY)
u = 0.8 'Concrete
Fric = u * N
v0 = 50
Hi_Res_Timer_Initialize
Milliseconds = Get_Elapsed_Seconds
Running = True
Game_Loop

End Sub

Public Sub Game_Loop()

Do While Running = True

DoEvents
Lock_FPS 60
Cls

If Flag = True Then

Time = Get_Elapsed_Seconds - Milliseconds
v = v0 - (Fric / m) * Time
X = x0 + v0 * Time - 0.5 * (Fric / m) * (Time * Time)

If v < 0 Or X < x0 Or X > frmmain.ScaleWidth Then

v = 0
X = x0
Flag = False

End If

End If

PSet (X, Y), RGB(0, 0, 0)
QueryPerformanceCounter Start_Time

Loop

End Sub

Private Sub Form_Activate()

Main

End Sub

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

If KeyCode = vbKeySpace And Flag = False Then

Milliseconds = Get_Elapsed_Seconds
Flag = True

End If

End Sub

Private Sub Form_Unload(Cancel As Integer)

Running = False
Unload Me
End

End Sub




[Edited by - Jacob Roman on January 9, 2006 9:45:43 PM]

Share this post


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

  • Advertisement