Author Topic: Line segment collision, rotational collision response?  (Read 1380 times)

0 Members and 1 Guest are viewing this topic.

Offline spathi

  • C= 64
  • **
  • Posts: 78
  • Karma: 5
    • View Profile
Does anyone have a function giving rotational impulse force from a collision of 2D vector objects?

This seems like it should be fairly simple to do on the basis of how many degrees object B is traversing with respect to some mass center of object a.  And the closer the traversing tangent line is to the mass center, the more momentum transfers into x/y velocity as opposed to angular velocity.

This doesn't has to be accurate, it only has to look OK.
« Last Edit: July 28, 2013 by spathi »

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
This thread might be of interest to you. ( Rigid Body Dynamics simulator )
http://www.dbfinteractive.com/forum/index.php?topic=1501.msg23060#msg23060

Challenge Trophies Won:

Offline spathi

  • C= 64
  • **
  • Posts: 78
  • Karma: 5
    • View Profile
Thank you.

Unfortunately the link shared in that thread appears to be broken.
« Last Edit: August 27, 2013 by spathi »

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
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
Code: [Select]
;---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
;--------------------------------------------------------------------------------------/

Challenge Trophies Won: