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