i put together this line-to-line physics demo. Part of the collision handling was taken from a circle colision demo, which is where my problem is.
When 2 circles collide, you only need to find 1 angle between them to handle the collision, when 2 lines collide you need 2 angles to handle collsion. I've tried to modify the code to use 2 angles but every time just makes it worse.
The documentation at the beginning was for me to remind myself exactly how to handle everything, so you can ignore it. The collision that i need help on are in the UpdateLynes() function.
Just use the arrow keys to make one of the lines move.
(btw, this is 2d)
When 2 circles collide, you only need to find 1 angle between them to handle the collision, when 2 lines collide you need 2 angles to handle collsion. I've tried to modify the code to use 2 angles but every time just makes it worse.
The documentation at the beginning was for me to remind myself exactly how to handle everything, so you can ignore it. The collision that i need help on are in the UpdateLynes() function.
Just use the arrow keys to make one of the lines move.
;find the % of each mass it will take based off the distance from each point ; a=line dist ; b=dist from point 1 ; mass1=mass of first point ; mass2=mass of second point ; p1=percent for point 1 ; p2=percent for point 2 ; p2=b/a ; p1=1.0-p2 ;find out the mass of the point of contact ; tmass=total mass for PoC ; tmass=p1*mass1+p2*mass2 ;find the velocities of the PoC ; tvelx=total x velocity for the PoC ; tvely=total y velocity for the PoC ; p1xv/yv=x/y velocity of point 1 ; p2xv/yv=x/y velocity of point 2 ; tvelx=p1*p1xv+p2*p2xv ; tvely=p1*p1yv+p2*p2yv ;find the same for the other point ; tmass1=mass for other line's PoC ; tvelx1=x velocity for other line's PoC ; tvely1=y velocity for other line's PoC ;perfrom circle collision with the calculated values ;based on the offset of the x/y's and percent's, affect the points accordingly ; sx=amount tvelx shifted ; sy=amount tvely shifted ; p1xv=p1xv+sx*p1 ; p1yv=p1yv+sy*p1 ; p2xv=p2xv+sx*p2 ; p2yv=p2yv+sy*p2 Graphics 800,600,16,2 Global linx#,liny# Type point Field x#,y# Field xv#,yv# Field fx#,fy# Field mass# End Type Type lyne Field a.point Field b.point Field dist# Field tension# Field cur_d# End Type a.point=CreatePoint(100,100,.99,.99,0,0,1) b.point=CreatePoint(200,100,.99,.99,0,0,10) CreateLyne(a,b,100,1) For i=0 To 20 CreateLyne(CreatePoint(300+i*5,100,.99,.99,0,0,1),CreatePoint(300+i*5,200,.99,.99,0,0,1),100,1) Next SetBuffer BackBuffer() While KeyHit(1)=0 Cls If KeyDown(200)=1 ;a\yv=a\yv-.1 b\yv=b\yv-.1 EndIf If KeyDown(208)=1 ;a\yv=a\yv+.1 b\yv=b\yv+.1 EndIf If KeyDown(203)=1 ;a\xv=a\xv-.1 b\xv=b\xv-.1 EndIf If KeyDown(205)=1 ;a\xv=a\xv+.1 b\xv=b\xv+.1 EndIf UpdatePoints(1) UpdateLynes() Flip Wend Function CreatePoint.point(x#,y#,fx#,fy#,xv#,yv#,mass#) p.point=New point p\x=x p\y=y p\xv=xv p\yv=yv p\fx=fx p\fy=fy p\mass=mass Return p End Function Function CreateLyne.lyne(a.point,b.point,dist#,tension#) l.lyne=New lyne l\a=a l\b=b l\dist=Sqr((a\x-b\x)*(a\x-b\x)+(a\y-b\y)*(a\y-b\y)) If dist>0 Then l\dist=dist l\cur_d=l\dist l\tension=tension Return l End Function Function UpdatePoints(boundries=0) For p.point=Each point p\xv=p\xv*p\fx p\yv=p\yv*p\fy p\x=p\x+p\xv p\y=p\y+p\yv If boundries=1 If p\x<0 p\x=0 p\xv=-p\xv EndIf If p\x>800 p\x=800 p\xv=-p\xv EndIf If p\y<0 p\y=0 p\yv=-p\yv EndIf If p\y>600 p\y=600 p\yv=-p\yv EndIf EndIf Next End Function Function UpdateLynes() For l.lyne=Each lyne d#=Sqr((l\a\x-l\b\x)*(l\a\x-l\b\x)+(l\a\y-l\b\y)*(l\a\y-l\b\y)) If d=0 Then d=.0001 diff#=((d-l\dist)/d)*l\tension x#=(l\a\x-l\b\x) y#=(l\a\y-l\b\y) mass1#=l\a\mass/(l\a\mass+l\b\mass) mass2#=l\b\mass/(l\a\mass+l\b\mass) x0#=-x*mass2*l\a\fx*diff l\a\x=l\a\x+x0 l\a\xv=l\a\xv+x0 y0#=-y*mass2*l\a\fy*diff l\a\y=l\a\y+y0 l\a\yv=l\a\yv+y0 x1#=x*mass1*l\b\fx*diff l\b\x=l\b\x+x1 l\b\xv=l\b\xv+x1 y1#=y*mass1*l\b\fy*diff l\b\y=l\b\y+y1 l\b\yv=l\b\yv+y1 l\cur_d=d-diff Line l\a\x,l\a\y,l\b\x,l\b\y Next For l.lyne=Each lyne ll.lyne=l While ll<>Last lyne ll=After ll ;For ll.lyne=Each lyne ;check to see if the lines are colliding If LinesCross(l\a\x,l\a\y,l\b\x,l\b\y,ll\a\x,ll\a\y,ll\b\x,ll\b\y)=1 d1#=Sqr((l\a\x-linx)*(l\a\x-linx)+(l\a\y-liny)*(l\a\y-liny)) d2#=Sqr((ll\a\x-linx)*(ll\a\x-linx)+(ll\a\y-liny)*(ll\a\y-liny)) ;calculate the %'s of the masses and velocities based on where the point of contact is on each line p2#=d1/l\cur_d If p2>1.0 Then p2=1.0 p1#=1.0-p2 p4#=d2/ll\cur_d If p4>1.0 Then p4=1.0 p3#=1.0-p4 tmass1#=p1*l\a\mass+p2*l\b\mass tmass2#=p3*ll\a\mass+p4*ll\b\mass tvelx1#=p1*l\a\xv+p2*l\b\xv tvely1#=p1*l\a\yv+p2*l\b\yv tvelx2#=p3*ll\a\xv+p4*ll\b\xv tvely2#=p3*ll\a\yv+p4*ll\b\yv angle#=ATan2((l\a\y+l\b\y)/2.0-(ll\a\y+ll\b\y)/2.0,(l\a\x+l\b\x)/2.0-(ll\a\x+ll\b\x)/2.0)+180 ;find the how much is crossing over the other line If d1>l\cur_d/2.0 Then d1=l\cur_d-d1 If d2>ll\cur_d/2.0 Then d2=ll\cur_d-d2 x#=Cos(angle) y#=Sin(angle) mass1#=tmass2/(tmass1+tmass2) mass2#=tmass1/(tmass1+tmass2) offset#=Sqr(d1+d2) l\a\x=l\a\x-x*offset*p1*mass1 l\a\y=l\a\y-y*offset*p1*mass1 l\b\x=l\b\x-x*offset*p2*mass1 l\b\y=l\b\y-y*offset*p2*mass1 ll\a\x=ll\a\x+x*offset*p3*mass2 ll\a\y=ll\a\y+y*offset*p3*mass2 ll\b\x=ll\b\x+x*offset*p4*mass2 ll\b\y=ll\b\y+y*offset*p4*mass2 ;------------------------- q1# = min(p1, p2) q2# = min(p3, p4) qt# = q1 + q2 a1# = ATan2(l\b\y-l\a\y, l\b\x-l\a\x) If l\b\x-l\a\x < 0 Then a1 = a1 + 180 a2# = ATan2(ll\b\y-ll\a\y, ll\b\x-ll\a\x) If ll\b\x-ll\a\x < 0 Then a2 = a2 + 180 angle# = (a1*q1 + a2*q2) / qt - 90 x#=Cos(angle) y#=Sin(angle) ;------------------------- v1#=tvelx1*x+tvely1*y v2#=tvelx2*x+tvely2*y p#=(2.0*(v1-v2))/(tmass1+tmass2) tvelx1=-p*tmass2*x tvely1=-p*tmass2*y tvelx2=p*tmass1*x tvely2=p*tmass1*y l\a\xv=l\a\xv+tvelx1*p1 l\a\yv=l\a\yv+tvely1*p1 l\b\xv=l\b\xv+tvelx1*p2 l\b\yv=l\b\yv+tvely1*p2 ll\a\xv=ll\a\xv+tvelx2*p3 ll\a\yv=ll\a\yv+tvely2*p3 ll\b\xv=ll\b\xv+tvelx2*p4 ll\b\yv=ll\b\yv+tvely2*p4 EndIf ;Next Wend Next End Function Function min#(x#,y#) If x<y Then Return x Return y End Function Function LinesCross(x0#,y0#,x1#,y1#,x2#,y2#,x3#,y3#) n#=(y0-y2)*(x3-x2)-(x0-x2)*(y3-y2) d#=(x1-x0)*(y3-y2)-(y1-y0)*(x3-x2) If (Abs(d)<0.0001) Then Return 0 Sn#=(y0-y2)*(x1-x0)-(x0-x2)*(y1-y0) AB#=n/d If AB>0.0 And AB<1.0 CD#=Sn/d If CD>0.0 And CD<1.0 linx=x0+AB*(x1-x0) liny=y0+AB*(y1-y0) Return 1 EndIf EndIf Return 0 End Function
(btw, this is 2d)