Code archives/Graphics/vector point to line deflection
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| I have been trying to learn vector math. and is a little bit complicate but nothing I can't Manage. I googled and found this site http://tonypa.pri.ee/vectors/start.html it is a good tutorial source. it is for flash but the logic/principal is the same. so I did some work around it and managed to figure out a few things. so here is what I got so far. if you like it let me know so I can post a ball to line sample when I figure it out. | |||||
SuperStrict
Type point
Field x#
Field y#
End Type
Type tgame
Field stageW%
Field stageH%
Field maxV#
Field gravity#
Field bounce:vector2d
Field t#
Field MyOb:vector2d
Field v1:vector2d[5]
End Type
Type vector2d
Field p0:point
Field p1:point
Field vx#,vy#
Field dx#,dy#
Field rx#,ry#
Field lx#,ly#
Field Length#
Field timeFrame#
Field lastTime#
Global airf#
Global b#
Global f#
End Type
Global game:tgame = New tgame
game.stageW = 320
game.stageH = 240
game.maxV = 10
game.gravity = 0.0;
' Create Object
' point p0 is its starting point in the coordinates x/y
game.myob = New vector2d
game.myOb.airf = 1.0
game.myOb.b = 1.0
game.myOb.f = 1.0
game.myOb.p0 = New point
game.myOb.p0.x = 150
game.myob.p0.y = 100
' vectors x/y components
game.myOb.vx = 1.0;
game.myOb.vy = 0.0;
game.myOb.lastTime = MilliSecs()
' Create first vector
' point p0 is its starting point in the coordinates x/y
' point p1 is its End point in the coordinates x/y
game.v1[1] = New vector2d
game.v1[2] = New vector2d
game.v1[3] = New vector2d
game.v1[4] = New vector2d
game.v1[1].p0 = New point
game.v1[1].p1 = New point
game.v1[1].p0.x = 5
game.v1[1].p0.y = 10
game.v1[1].p1.x = 250
game.v1[1].p1.y = 50
game.v1[1].b = 1.0
game.v1[1].f = 1.0
game.v1[2].p0 = New point
game.v1[2].p1 = New point
game.v1[2].p0.x = 250
game.v1[2].p0.y = 50
game.v1[2].p1.x = 280
game.v1[2].p1.y = 130
game.v1[2].b = 1
game.v1[2].f = 1
game.v1[3].p0 = New point
game.v1[3].p1 = New point
game.v1[3].p0.x = 280
game.v1[3].p0.y = 130
game.v1[3].p1.x = 50
game.v1[3].p1.y = 160
game.v1[3].b = 1
game.v1[3].f = 1
game.v1[4].p0 = New point
game.v1[4].p1 = New point
game.v1[4].p0.x = 50
game.v1[4].p0.y = 160
game.v1[4].p1.x = 5
game.v1[4].p1.y = 10
game.v1[4].b = 1
game.v1[4].f = 1
Graphics game.stageW,game.stageH,32
Repeat
Cls
runme()
Flip()
Until KeyDown(key_escape)
Function runMe ()
Local i%
For i = 1 To 4
updateVector(game.v1[i]);
Next
Local ob:vector2d = game.myOb;
' add air resistance
ob.vx :* ob.airf
ob.vy :* ob.airf
' dont let it go over Max speed
If (ob.vx>game.maxV)
ob.vx = game.maxV
ElseIf (ob.vx<-game.maxV)
ob.vx = -game.maxV
EndIf
If (ob.vy>game.maxV)
ob.vy = game.maxV
Else If (ob.vy<-game.maxV)
ob.vy = -game.maxV
EndIf
' update the vector parameters
updateObject(ob)
' time To collide something big
game.t = 1000000
' no collision yet
game.bounce = Null
' find collisions with walls
For Local i% = 1 To 4
Local t% = findIntersection(ob, game.v1[i]);
' If this has collision, save it
If (t<game.t)
' which wall To collide with
game.bounce = game.v1[i];
' save time
game.t = t;
EndIf
Next
' we have collision
If game.bounce
' set End point To intersection point
ob.p1.x = ob.p0.x+ob.vx*game.t;
ob.p1.y = ob.p0.y+ob.vy*game.t;
' bounce
Local newv:vector2d = bounce(ob, game.bounce);
' change movement vector
ob.vx = newv.vx;
ob.vy = newv.vy;
' add New direction To End point
ob.p1.x :+ ob.vx*(1-game.t);
ob.p1.y :+ ob.vy*(1-game.t);
' save the time
game.t = 1-game.t;
EndIf
' reset Object To other side If gone out of stage
If (ob.p1.x>game.stageW)
ob.p1.x :- game.stageW;
ElseIf (ob.p1.x<0)
ob.p1.x :+ game.stageW;
EndIf
If (ob.p1.y>game.stageH)
ob.p1.y :- game.stageH;
ElseIf (ob.p1.y<0)
ob.p1.y :+ game.stageH;
EndIf
' draw it
drawAll(ob);
' make End point equal To starting point For Next cycle
ob.p0 = ob.p1;
' save the movement without time
ob.vx :/ ob.timeFrame;
ob.vy :/ ob.timeFrame;
End Function
' Function To find all parameters For the vector
Function updateVector (v:vector2d)
' x And y components
' End point coordinate - start point coordinate
v.vx = v.p1.x-v.p0.x;
v.vy = v.p1.y-v.p0.y;
' length of vector
v.Length = Sqr(v.vx*v.vx+v.vy*v.vy);
' normalized unti-sized components
If (v.Length>0)
v.dx = v.vx/v.Length;
v.dy = v.vy/v.Length;
Else
v.dx = 0;
v.dy = 0;
EndIf
' Right hand normal
v.rx = -v.vy;
v.ry = v.vx;
' Left hand normal
v.lx = v.vy;
v.ly = -v.vx;
End Function
Function updateObject (v:vector2d)
' find time passed from last update
Local thisTime# = MilliSecs()
Local time# = (thisTime-v.lastTime)/6.0
' we use time, Not frames To move so multiply movement vector with time passed
v.vx :* time;
v.vy :* time;
' add gravity, also based on time
v.vy = v.vy+time*game.gravity;
'v.p1 = {};
v.p1 = New point
' find End point coordinates
v.p1.x = v.p0.x+v.vx;
v.p1.y = v.p0.y+v.vy;
' length of vector
v.Length = Sqr(v.vx*v.vx+v.vy*v.vy);
' normalized unti-sized components
v.dx = v.vx/v.Length;
v.dy = v.vy/v.Length;
' Right hand normal
v.rx = -v.vy;
v.ry = v.vx;
' Left hand normal
v.lx = v.vy;
v.ly = -v.vx;
' save the current time
v.lastTime = thisTime;
' save time passed
v.timeFrame = time;
End Function
' find intersection point of 2 vectors
Function findIntersection:Int (v1:vector2d, v2:vector2d)
' vector between starting points
Local t1#,t2#
Local v3a:vector2d = New vector2d
Local v3b:vector2d = New Vector2d
v3a.vx = v2.p0.x - v1.p0.x
v3a.vy = v2.p0.y - v1.p0.y
v3b.vx = v1.p0.x - v2.p0.x
v3b.vy = v1.p0.y - v2.p0.y
' If they are parallel vectors, Return big number
If ((v1.dx = v2.dx And v1.dy = v2.dy) Or (v1.dx = -v2.dx And v1.dy = -v2.dy))
Return 1000000;
Else
t1 = perP(v3a, v2)/perP(v1, v2)
t2 = perP(v3b, v1)/perP(v2, v1)
EndIf
If (t1>0 And t1<=1 And t2>0 And t2<=1)
Return t1;
Else
Return 1000000;
EndIf
End Function
' calculate perp product of 2 vectors
Function perP# (va:vector2d, vb:vector2d)
Return va.vx*vb.vy-va.vy*vb.vx;
End Function
' find New vector bouncing from v2
Function bounce:vector2d (v1:vector2d, v2:vector2d)
' projection of v1 on v2
Local proj1:vector2d = projectVector(v1, v2.dx, v2.dy);
' projection of v1 on v2 normal
Local proj2:vector2d = projectVector(v1, v2.lx/v2.Length, v2.ly/v2.Length);
Local proj:vector2d = New vector2d
' reverse projection on v2 normal
proj2.vx :* -1;
proj2.vy :* -1;
' add the projections
proj.vx = v1.f*v2.f*proj1.vx+v1.b*v2.b*proj2.vx;
proj.vy = v1.f*v2.f*proj1.vy+v1.b*v2.b*proj2.vy;
Return proj;
End Function
Function projectVector:vector2d (v1:vector2d, dx#, dy#)
' find dot product
Local dp# = v1.vx*dx+v1.vy*dy;
Local proj:vector2d = New vector2d
' projection components
proj.vx = dp*dx;
proj.vy = dp*dy;
Return proj;
End Function
Function drawall(v:vector2d)
Local vn:vector2d
For Local i:Int = 1 To 4
vn = game.v1[i]
DrawLine vn.p0.x,vn.p0.y,vn.p1.x,vn.p1.y
Next
DrawOval v.p0.x-2,v.p0.y-2,4,4
End Function |
Comments
| ||
| Updated for Monkey! includes a vector class and objects. made an engine that will be expanded for the other vector demos. |
Code Archives Forum