Code archives/Graphics/vector point to line deflection

This code has been declared by its author to be Public Domain code.

Download source code

vector point to line deflection by Jesse2008
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

Jesse2012
Updated for Monkey!

includes a vector class and objects.

made an engine that will be expanded for the other vector demos.




Code Archives Forum