Code archives/Algorithms/vectors part 7
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| ball to arc collision(collision point) does not include response. based on tutorials by TonyPa: http://tonypa.pri.ee/vectors/tut12.html | |||||
'*************************************************************
' Ball to Arc Collision
'
' author: Jesus Perez
' created: 10/11/2010
' based on tutorial Vectors for Flash by TonyPa
' tutorial located at: http://tonypa.pri.ee/vectors/tut12.html
'*************************************************************
SuperStrict
'Create game Object
Type Tgame
Field stageW:Float
Field stageH:Float
Field maxV:Float
Field gravity:Float
Field LastTime:Float
Field myOb:Tball
Field vc:Tvector
Field v3:Tvector
Field vn:Tvector
Field v4:Tvector
Field v5:Tvector
Field p2:tpoint
Field p3:Tpoint
Field totalRadius:Float
Field arc:Tvector
Method New()
arc = New Tvector
myOb = New Tball
vc = New Tvector
v3 = New Tvector
vn = New Tvector
v4 = New Tvector
v5 = New Tvector
p2 = New Tpoint
p3 = New Tpoint
stageW = 320
stageH = 240
'Create game Object
'Create Object
'point p0 is its starting point in the coordinates x/y
myOb.r = 40
myOb.p0.x=50
myOb.p0.y=50
myOb.p1.x=250
myOb.p1.y=150
myOb.arc = New Tvector
myOb.update(True)
'balls
arc.p0.x = 160
arc.p0.y = 80
arc.r = 60
arc.ang1=-60
arc.ang2=80
arc.arc= New Tvector
Tarc.findArc(arc)
arc.update(True)
End Method
'Function To draw the points, lines And show text
Method drawAll(v:Tvector)
'draw ob path
DrawLine v.p0.x,v.p0.y,v.p1.x,v.p1.y
'place ob mc
Tball.drawCircle(v.p2.x,v.p2.y,v.r)
v=game.arc
'draw arc
Tarc.drawArc(v.p0.x, v.p0.y, v.r, v.ang1, v.ang2)
'line
'DrawLine(v.arc.p0.x, v.arc.p0.y,v.arc.p1.x,v.arc.p1.y)
End Method
End Type
Type Tpoint
Field x:Float
Field y:Float
End Type
Type Tvector
Field p0:Tpoint
Field p1:Tpoint
Field p2:Tpoint
Field length:Float
Field dx:Float
Field dy:Float
Field vx:Float
Field vy:Float
Field vx1:Float
Field vy1:Float
Field vx2:Float
Field vy2:Float
Field ang1:Float
Field ang2:Float
Field rx:Float
Field ry:Float
Field lx:Float
Field ly:Float
Field b:Float
Field f:Float
Field r:Float
Field m:Float
Field airf:Float
Field lastTime:Float
Field timeFrame:Float
Field arc:Tvector
Method New()
p0 = New Tpoint
p1 = New Tpoint
p2 = New Tpoint
End Method
'Function To find all parameters For the vector
Method update( frompoints:Int=False)
'x And y components
If(frompoints)
vx=p1.x-p0.x
vy=p1.y-p0.y
Else
p1.x=p0.x+vx
p1.y=p0.y+vy
EndIf
'length of vector
Length=Sqr(vx*vx+vy*vy)
'normalized unit-sized components
If(Length>0)
dx=vx/Length
dy=vy/Length
Else
dx=0
dy=0
EndIf
'Right hand normal
rx = -dy
ry = dx
'Left hand normal
lx = dy
ly = -dx
End Method
'project vector v1 on unit-sized vector dx/dy
Method projectVector:Tvector(dx:Float, dy:Float)
'find dot product
Local dp:Float = vx*dx + vy*dy
Local proj:Tvector=New Tvector
'projection components
proj.vx=dp*dx
proj.vy=dp*dy
Return proj
End Method
'calculate dot product of 2 vectors
Method dotP:Float(v2:Tvector)
Return vx*v2.vx + vy*v2.vy
End Method
End Type
Type Tball Extends Tvector
Field vc:Tvector
Method New()
If vc=Null vc = New Tvector
p2 =New Tpoint
End Method
Function drawcircle(x:Float,y:Float,r:Float)
For Local a:Float = 0 Until 360
Local vx:Float = Cos(a)*r
Local vy:Float = Sin(a)*r
Plot x+vx,y+vy
Next
End Function
'find collision between balls
Method ballvsBall:Tvector(p1:Tpoint, r:Float)
'vector between center points of balls
'game.vc={}
vc.vx = p1.x-p0.x
vc.vy = p1.y-p0.y
'projection of vc on movement vector
Local vp:Tvector=vc.projectVector(dx, dy)
'vector To center of arc in direction of movement vectors normal
'game.vn={}
game.p2.x = p0.x+vp.vx
game.p2.y = p0.y+vp.vy
game.vn.p0=game.p2
game.vn.p1=p1
game.vn.update(True)
'sum of radius
game.totalRadius=Self.r+r
'check If vn is shorter Then combined radiuses
Local diff:Float = game.totalRadius-game.vn.Length
If (diff>0)
'collision
'amount To move back moving ball
Local moveBack:Float=Sqr(game.totalRadius*game.totalRadius-game.vn.Length*game.vn.Length)
game.p3.x = game.vn.p0.x-moveBack*dx
game.p3.y = game.vn.p0.y-moveBack*dy
game.v3.p0 = p0
game.v3.p1 = game.p3
game.v3.update(True)
'check If p3 is on the movement vector
If(game.v3.Length<Length And game.v3.dotP(Self)>0)
Return game.v3
EndIf
EndIf
Return Null
End Method
End Type
Type Tarc Extends Tvector
'find End points of the arc from angles
Function findArc(v:Tvector)
'vector between End points of the arc
v.arc.p0.x = v.p0.x+v.r*Cos(v.ang1)
v.arc.p0.y = v.p0.y+v.r*Sin(v.ang1)
v.arc.p1.x = v.p0.x+v.r*Cos(v.ang2)
v.arc.p1.y = v.p0.y+v.r*Sin(v.ang2)
v.arc.update(True)
End Function
Function DrawArc(x:Float, y:Float, radius:Float, startAngle:Float, endAngle:Float)
Local fx:Float,fy:Float 'first x,y
Local lx:Float,ly:Float 'last x,y
Const RATE:Float = Pi/180.0
If startAngle = endAngle Then Return
If startAngle > endAngle
Local ta:Float = endAngle
endAngle = startAngle
startAngle = ta
EndIf
Local angle:Float = endAngle - StartAngle
If angle > 360.0 angle = 360.0
Local Stp:Float = 1/(RATE * radius)
Local AccumAngle:Float = StartAngle
While accumAngle < (StartAngle+Angle)
lx:Float = Cos((accumAngle)) * radius
ly:Float = Sin((accumAngle)) * radius
Plot x + lx, y + ly
AccumAngle :+ stp
Wend
End Function
End Type
'Create game Object
Global game:Tgame = New Tgame
'collision
Function findCollision()
'start To calculate movement
Local ob:Tball=game.myOb
Local ob1:Tvector=game.arc
ob.update(True)
ob1.update(True)
Local collision:Tvector=ob.ballvsBall(ob1.p0, ob1.r)
If(collision)
'collision point found
game.v5 = New Tvector
game.v5.p0 = ob1.p0
game.v5.p1 = game.p3
game.v5.update(True)
'check If the point is on the Right side of vector between arc points
'vector between starting point of arc And collision point
game.v4= New Tvector
game.v4.p0 = ob1.arc.p0
game.v4.p1.x = ob1.p0.x+game.v5.dx*ob1.r
game.v4.p1.y = ob1.p0.y+game.v5.dy*ob1.r
game.v4.update(True)
Local arcNormal:Tvector = New Tvector
arcNormal.vx = ob1.arc.lx
arcNormal.vy = ob1.arc.ly
If(game.v4.dotP(arcNormal)>=0)
ob.p2.y=game.p3.y
ob.p2.y=game.p3.y
Else
'Not on the arc
collision = Null
EndIf
EndIf
'need To check with other side of arc too
If(collision= Null)
If(game.vn.Length<ob1.r)
'amount To move back moving ball
Local r:Float=ob1.r-ob.r
Local moveForward:Float=Sqr(r*r-game.vn.Length*game.vn.Length)
game.p3.x = game.vn.p0.x+moveForward*ob.dx
game.p3.y = game.vn.p0.y+moveForward*ob.dy
game.v3.p0 = ob.p0
game.v3.p1 = game.p3
game.v3.update(True)
'check If p3 is on the movement vector
If(game.v3.Length<ob.Length And game.v3.dotP( ob)>0)
'collision point found
game.v5.p0 = ob1.p0
game.v5.p1 = game.p3
game.v5.update(True)
'check If the point is on the Right side of vector between arc points
'vector between starting point of arc And collision point
game.v4.p0 = ob1.arc.p0
game.v4.p1.x = ob1.p0.x+game.v5.dx*ob1.r
game.v4.p1.y = ob1.p0.y+game.v5.dy*ob1.r
game.v4.update(True)
Local arcNormal:Tvector = New Tvector
arcNormal.vx = ob1.arc.lx
arcNormal.vy = ob1.arc.ly
If(game.v4.dotP(arcNormal)>=0)
ob.p2.x=game.p3.x
ob.p2.y=game.p3.y
collision=game.v3
EndIf
EndIf
EndIf
'now we need To check If endpoints of arc are being hit
Local nextCollision:Tvector = ob.ballvsBall(ob1.arc.p0, 0)
If(nextCollision)
If(collision=Null Or nextCollision.Length<collision.Length)
collision=nextCollision
ob.p2.x = game.p3.x
ob.p2.y = game.p3.y
EndIf
EndIf
nextCollision=ob.ballvsBall(ob1.arc.p1, 0)
If(nextCollision)
If(collision=Null Or nextCollision.Length<collision.Length)
collision=nextCollision
ob.p2.x=game.p3.x
ob.p2.y=game.p3.y
EndIf
EndIf
EndIf
If(collision=Null)
'no collision
ob.p2=ob.p1
EndIf
'draw it
game.drawAll(ob)
End Function
Graphics 640,480
Cls
findCollision()
Flip()
WaitKey() |
Comments
None.
Code Archives Forum