[RESOLVED] Friction Coefficient Too High!

Started by
7 comments, last by Jacob Roman 18 years, 3 months ago
I'm having an object move fast, and make a quick stop, to where it looks like a car slams on the brakes, and friction takes over, only I'm not doing this for cars. Anyways, the coefficient suppose to be like just under 1, like around 0.9 or 0.8, but I had to crank it up to 25 to get the effect I'm looking for. My maths seem correct, but it looks as though something is missing. Here are the values I initialized: X = 50 Y = 200 x0 = X y0 = Y m = 150 * POUNDS_TO_KILOGRAMS N = m * GRAVITY u = 25 Fric = u * N v0 = 200 The formulas I used: v = v0 - (Fric / m) * Time X = x0 + v0 * Time - 0.5 * (Fric / m) * (Time * Time) And 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 = 25 'Concrete
    Fric = Friction_Force(u, N)
    v0 = 200
    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 11, 2006 9:31:52 PM]
Advertisement
The friction coefficient is not too high, but maybe it's the initial speed (around 450 mph).

If a object moving 200 m/s has a frictional coefficient of ~0.9, it will decelerate at 8.8 m/s/s under standard gravity. A complete stop will take over 22 seconds.
Yeah but I wanted it to stop around 1 or 2 seconds.
I've been following your threads for a bit, and I can say that if a 150lb person hit the ground at 450mph, then it would be expected that the would skid for a little bit first.

Well, maybe splatter would be a better term. [smile]

Anyways, if you want to make it stop quicker than what is 'realistic', then you have to artifically increase friction, mass, or gravity, or introduce an extra stopping force.

Any way you do it, you'll have to fudge it a little to get the result you want.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
I'm more after realism, but maybe if I play around with the values, I might be able to achieve what I'm looking for. I do have an idea though. You guys say that this is 1 meter per pixel. What if I were to multiply it by a scale factor to make a meter any size I want so it isn't limited to one pixel? Is this ok?
Well, even if you change what a meter looks like, it won't change how much distance it takes to come to a stop.

So you want to find some acceleration a that stops an object in time t=2s?
Solving this:
v = v0 + at
0 = 200 + 2a
a=-100 m s-2

Getting this kind of acceleration out of a 70kg man requires 7000 N.

If you rely on friction, then your force has to each some u where
700N u = 7000N
So u = 10 is just fine.

You could also cut some of the person's momentum at impact, because such collisions are never very elastic.

Let's say we use a high, but more realistic u of 2. Now we have
v = v0 + (-umg/m)t
So let's find v0.
0 = v0 - 40
v0 = 40

That means the initial momentum should be
v0 * m = 2800

In your original conditions, v0 was 200, so p = 200 * 70 = 14000
The ratio is 0.2, therefore you could have the initial impact with the
ground absorb 80% of the object's momentum. This wouldn't be majorly unrealistic.

If you wanted to make it more realistic, then the momentum absorbed should have the cosine of the angle of impact as a factor. Dropping straight to the ground maximizes transfer of energy to the ground, while hitting at an acute angle still sends you pretty far.
We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
I'm just working with 1D kinematics for now. Anyways, changing the meter size will help cause I can keep my coefficient at 0.9, lower my initial velocity down to a reasonable number, like around 1 to 10, and get the effect I'm looking for. Someone from another forum told me that this was ok to multiply it by a scale factor. So I'm gonna try it and see what I get when I get home.
Well, good luck.

We''re sorry, but you don''t have the clearance to read this post. Please exit your browser at this time. (Code 23)
And you know what. It works!!! I was right! Thanks for everyones help. I had to make the coefficient 5 though so it makes a screeching halt.

Here's the source code:

 Option Explicit'92 Pixels'5 Ft 10 In'70 In'1.778 m'1 meter = 92/1.778 = 51.7435320585927Private Declare Function QueryPerformanceCounter Lib "Kernel32" (lpPerformanceCount As Currency) As LongPrivate Declare Function QueryPerformanceFrequency Lib "Kernel32" (lpPerformanceCount As Currency) As LongPrivate Const GRAVITY As Single = 9.80665Private Const POUNDS_TO_KILOGRAMS As Single = 0.45359237Private Const AIR_DENSITY As Single = 1.29 '0.00129Private Const METERS_TO_FEET As Single = 3.2808399Private Const FEET_TO_METERS As Single = 0.3048Private Const METERS_TO_INCHES As Single = 39.3700787Private Const INCHES_TO_METERS As Single = 0.0254Private Const PIXELS_TO_METERS As Single = 51.7435320585927Private Running As BooleanPrivate Time As SinglePrivate Milliseconds As SinglePrivate Ticks_Per_Second As CurrencyPrivate Start_Time As CurrencyPrivate Flag As BooleanPrivate X As Single, Y As Single   'X and Y positionPrivate x0 As Single, y0 As Single 'Initial positionPrivate t As Single                'TimePrivate v As Single                'VelocityPrivate m As Single                'MassPrivate a As Single                'AccelerationPrivate v0 As Single               'Initial VelocityPrivate F As Single                'Net ForcePrivate N As Single                'Normal ForcePrivate u As Single                'Dynamic Friction CoefficientPrivate Fric As Single             'Friction ForcePrivate Scalar As SinglePrivate 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 IfEnd FunctionPrivate 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_TimeEnd FunctionPrivate 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_TimeEnd FunctionPrivate Function Physics_Jump(ByVal v0 As Single, ByVal a As Single, ByVal t As Single) As Single    Physics_Jump = (v0 + a * t)End FunctionPrivate Function Physics_Air_Resistance(C As Single, p As Single, Area As Single, v As Single)        'F = C*p*A*v²/2    Physics_Air_Resistance = (C * p * Area * (v * v)) * 0.5End FunctionPrivate Function Physics_Normal_Force(m As Single, g As Single) As Single    Physics_Normal_Force = m * gEnd FunctionPrivate Function Physics_Net_Force(m As Single, a As Single) As Single    Physics_Net_Force = m * aEnd FunctionPrivate Function Physics_Friction_Force(u As Single, N As Single) As Single    Physics_Friction_Force = u * NEnd FunctionPublic Sub Main()    With frmMain            .Caption = "Press Space"        .ScaleMode = 3        .AutoRedraw = True        .DrawWidth = 10            End With        X = 50    Y = 200    x0 = X    y0 = Y    a = 1    m = 175 * POUNDS_TO_KILOGRAMS    F = Physics_Net_Force(m, a)    v0 = F / m    N = Physics_Normal_Force(m, GRAVITY)    Scalar = PIXELS_TO_METERS    u = 5    Fric = Physics_Friction_Force(u, N)    Hi_Res_Timer_Initialize    Milliseconds = Get_Elapsed_Seconds    Running = True    Game_Loop    End SubPublic Sub Game_Loop()    Do While Running = True            DoEvents        Lock_FPS 60        Cls                Print X, v, Time                If Flag = True Then                    Time = Get_Elapsed_Seconds - Milliseconds            v = v0 - ((Fric / m) * Time) / Scalar            X = x0 + v0 * Time * Scalar - 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        LoopEnd SubPrivate Sub Form_Activate()    MainEnd SubPrivate 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 SubPrivate Sub Form_Unload(Cancel As Integer)    Running = False    Unload Me    End    End Sub

This topic is closed to new replies.

Advertisement