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
[RESOLVED] Friction Coefficient Too High!
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:
[Edited by - Jacob Roman on January 11, 2006 9:31:52 PM]
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.
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.
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.
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.
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.
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.
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.
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:
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
Popular Topics
Advertisement