Sorry for the bad link the message I meant to link to was the first message on that page from Tetra. He shared some source code. The implementation seemed quite simple but the results where very nice.
Heres the Blitz Basic code he shared
;---rigid body.bb------------------------------------------------------------------------\
;
; rigid body
;
;
; by Tetra
;
;----------------------------------------------------------------------------------------/
AppTitle "Rigid Body Test 1.0"
SeedRnd( MilliSecs() )
;=======================================================================================|
; LOAD MODELS --|
;__Variables______________________________________
;
Type TSquare
Field x#
Field y#
Field a#
Field dx#
Field dy#
Field da#
Field odx#
Field ody#
Field oda#
Field mass#
Field velocity#
Field acceleration#
Field torque#
Field force#
Field time#
Field timePassed#
Field points#[8]
Field collided[4]
End Type
;
;------------------------------------------------
Function Load_Objects()
Local Square.TSquare
Square.TSquare = New TSquare
Square\x# = 512.0
Square\y# = 284.0
Square\a# = 20.0
Square\dx# = 0.0
Square\dy# = 0.0
Square\da# = 0.0
Square\odx# = 0.0
Square\ody# = 0.0
Square\oda# = 0.0
Square\mass# = 1.0
Square\time = MilliSecs()
End Function
;\---------------------------------------------------------------------------------------/
;=======================================================================================|
; DRAW SQUARES --|
;__Variables_____________________________________
;
;
;------------------------------------------------
Function DrawSquare()
Local Square.TSquare = First TSquare
Color 255,255,255
For i = 0 To 4 Step 2
Line Square\x# + Square\points[i],Square\y# + Square\points[i+1], Square\x# + Square\points[i+2],Square\y# + Square\points[i+3]
Next
Line Square\x# + Square\points[6],Square\y# + Square\points[7], Square\x# + Square\points[0],Square\y# + Square\points[1]
End Function
;----------------------------------------------------------------------------------------/
;=======================================================================================|
; GET ANGLE --|
;__Variables_____________________________________
;
;
; Get the angle between two vectors
;
; 0
; |
; -90 ==X== 90
; |
; 180
;------------------------------------------------
Function getAngle#( x1#,y1#, x2#,y2#, ox# = 0,oy# = 0 )
Local tvAx# = x1# - ox#
Local tvAY# = y1# - oy#
Local tvBx# = x2# - ox#
Local tvBY# = y2# - oy#
Local d# = ATan2#( tvAy#, tvAx# )
Local tvCx# = Cos#( d# ) * tvBx# + Sin#( d# ) * tvBy#
Local tvCy# = -Sin#( d# ) * tvBx# + Cos#( d# ) * tvBy#
Local newAngle# = ATan2#( tvCy#, tvCx# )
If ( newAngle# > 0.0 )
newAngle# = -(180.0 - newAngle#)
Else
newAngle# = -(-180.0 - newAngle#)
EndIf
Return newAngle#
End Function
;----------------------------------------------------------------------------------------/
;=======================================================================================|
; ANIMATE SQUARES --|
;__Variables_____________________________________
;
; g / 1s so 1pixel = 9.807 meters
Const Gravity# = 9.807 / 1000.0
;
;------------------------------------------------
Function AnimateSquare()
Local Square.TSquare = First TSquare
Local newX# = Square\x# + Square\dx#
Local newY# = Square\y# + Square\dy#
Local newA# = Square\a# + Square\da#
Local newVA# ;= Square\da#
Local bottom = 600
Local top = 100
Local leftb = 100
Local rightb = 900
Square\points[0] = 50.0 * Sin#( newA# - 45.0 )
Square\points[1] = 50.0 * Cos#( newA# - 45.0 )
Square\points[2] = 50.0 * Sin#( newA# + 45.0 )
Square\points[3] = 50.0 * Cos#( newA# + 45.0 )
Square\points[4] = 50.0 * Sin#( newA# + 135.0 )
Square\points[5] = 50.0 * Cos#( newA# + 135.0 )
Square\points[6] = 50.0 * Sin#( newA# - 135.0 )
Square\points[7] = 50.0 * Cos#( newA# - 135.0 )
;Color 0,255,0
;Line Square\x#,Square\y#, Square\x#+Square\vx#*10,Square\y#+Square\vy#*10
Local distance#, newAVel#, tempAVel#, tempXVel#, tempYVel#, impactX#, impactY#
Local reverseY = 0
Local reverseX = 0
Local Ejection#
Local angle#
tempXVel# = Square\dx#
tempYVel# = Square\dy#
Square\timePassed# = ( Float( MilliSecs() ) - Square\time# )
Square\time# = MilliSecs()
For i = 0 To 3
impactX# = Square\points[(i*2)]
impactY# = Square\points[(i*2)+1]
; this is a hack to make sure the box stays where it should do
; if it travelled as hyper speed it would fail ;)
; also the direction of the force wont simply reverse
If ( impactY# + newY# > bottom )
Ejection# = ( (impactY# + newY#) - bottom )
newY# = newY# - Ejection#
reverseY = 1
ElseIf ( impactY# + newY# < top )
Ejection# = ( top - (impactY# + newY#) )
newY# = newY# + Ejection#
reverseY = -1
EndIf
If ( impactX# + newX# >= rightb )
Ejection# = ( (impactX# + newX#) - rightb )
newX# = newX# - Ejection#
reverseX = 1
ElseIf ( impactX# + newX# < leftb )
Ejection# = ( leftb - (impactX# + newX#) )
newX# = newX# + Ejection#
reverseX = -1
EndIf
If ( reverseX <> 0 )Or( reverseY <> 0 )
;
; Force = Mass * Acceleration
; Acceleration is the rate of change in velocity over time a = v/t
;
Square\velocity# = VectorLength#( Square\dx# - Square\odx#, Square\dy# - Square\ody# )
Square\acceleration# = Square\velocity# / ( Square\timePassed# / 1000.0 )
Square\force# = Square\mass# * Square\acceleration#
;
; Angle between the direction vector and point of impact vector
;
angle# = -getAngle( impactX#,impactY#, Square\dx#, Square\dy# )
;
; torque = distance to center * Force * sin( angle )
;
distance# = VectorLength#( impactX#, impactY# )
Square\torque# = Square\force# * distance# * Sin( angle# )
;
; Convert torque to angular velocity
;
newVA# = newVA# + ( Square\torque# * 360.0 )
EndIf
Next
If reverseY = 1
tempYVel# = -Abs(Square\dy#) * 0.5
ElseIf reverseY = -1
tempYVel# = Abs(Square\dy#) * 0.5
EndIf
If reverseX = 1
tempXVel# = -Abs(Square\dx#) * 0.5
ElseIf reverseX = -1
tempXVel# = Abs(Square\dx#) * 0.5
EndIf
Square\x# = newX#
Square\y# = newY#
Square\a# = newA#
Square\odx# = Square\dx#
Square\ody# = Square\dy#
Square\dx# = tempXVel#
Square\dy# = tempYVel#
Square\da# = newVA#; * Float(Square\timePassed)
Square\dy# = Square\dy# + ( Gravity# * Square\timePassed# )
Color 128,128,128
Line leftb,bottom ,rightb,bottom
Line leftb,top ,rightb,top
Line leftb,top ,leftb,bottom
Line rightb,top ,rightb,bottom
End Function
;----------------------------------------------------------------------------------------/
;=======================================================================================|
; VECTOR LENGTH --|
;__Variables_____________________________________
;
;
;------------------------------------------------
Function VectorLength#( x#,y# )
Return Sqr#( x# * x# + y# * y# )
End Function
;----------------------------------------------------------------------------------------/
;=======================================================================================|
; READ INPUT --|
;__Variables_____________________________________
;
Global EXIT_PROGRAM = False
Global click = False
;
;------------------------------------------------
Function Read_Input()
If KeyDown(1) Then EXIT_PROGRAM = True
Local Square.TSquare = First TSquare
If MouseDown(1)
If Not click
Square\x# = 512
Square\y# = 384
Square\dx# = Rand(-100,100) / 10.0
Square\dy# = Rand(-100,100) / 10.0
Square\da# = Rand(-100,100) / 100.0
Square\a# = Rand(0,3600) / 10.0
click = True
EndIf
Else
click = False
EndIf
If MouseDown(2)
Square\x# = MouseX()
Square\y# = MouseY()
Square\dx# = MouseXSpeed()/4.0
Square\dy# = MouseYSpeed()/4.0
Square\da# = 0.0
EndIf
End Function
;----------------------------------------------------------------------------------------/
;=======================================================================================|
; INITIALIZE --|
;__Variables_____________________________________
;
Const GFX_WIDTH = 1024
Const GFX_HEIGHT = 768
Global timer
;
;------------------------------------------------
Function Initialize()
Graphics GFX_WIDTH, GFX_HEIGHT, 32, 2
timer = CreateTimer( 60 )
Load_Objects()
SetBuffer( BackBuffer() )
End Function
;----------------------------------------------------------------------------------------/
;=======================================================================================|
; MAIN --|
;__Variables_____________________________________
;
;
;------------------------------------------------
Function Main()
AnimateSquare()
DrawSquare()
Color 255,255,255
Text 10,10,"Right Click to randomize, Hold Left Click, drag then release to throw"
Local Square.TSquare = First TSquare
Text 10,30, "A Velocity: "+Square\da#
Text 10,50, "X Velocity: "+Square\dx#
Text 10,70, "Y Velocity: "+Square\dy#
End Function
;----------------------------------------------------------------------------------------/
;=======================================================================================|
; MAIN PROGRAM --|
;__Variables_____________________________________
;
;
;------------------------------------------------
Initialize()
While Not EXIT_PROGRAM
Read_Input()
Main()
Flip
Cls
WaitTimer( timer )
Wend
;----------------------------------------------------------------------------------------/
;=======================================================================================|
;-------------------------------------------------------------------------------- END --|
End
;--------------------------------------------------------------------------------------/