Code archives/Graphics/vectors part 2

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

Download source code

vectors part 2 by Jesse2008
this is the continuation from my point to line collition and deflection.
this is a ball to line collition and deflection with gravity.
now I have encapsulated it into objects. Maybe Easier to understand and use. I Hope. :)
note: collition is not constrained to the length of the line Which makes it only usefull for encapsulating.
next I will figure out vector segment and corner collition. comming soon. maybe :)
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
	Global walllist:TList
	Method Create(W%,H%,V#,G#)
    	walllist = CreateList()
		stageW = W
    	stageH = H
    	maxV = V
    	gravity = G
		myOb = New vector2d
	End Method
	Method createWall(x1#,y1#,x2#,y2#,b#,f#)
      ' Create vector
      ' point p0 is its starting point in the coordinates x/y
      ' point p1 is its End point in the coordinates x/y
		Local v:vector2d = New vector2d
		walllist.addlast(v)
		v.p0 = New point
		v.p0.x = x1
		v.p0.y = y1
		v.p1 =New point
		v.p1.x = x2
		v.p1.y = y2
		v.b = b
		v.f = f
		v.updateVector()
	End Method
      Method animate() 
         Local i%,w:vector2d,vb:vector2d,pen# 
		 Local MyOb:vector2d = game.myOb;
         ' add air resistance
         MyOb.vx :* MyOb.airf;
         MyOb.vy :* MyOb.airf;
         ' dont let it go over Max speed
         If (Myob.vx>game.maxV)
            MyOb.vx = game.maxV;
         Else If (MyOb.vx<-game.maxV)
            MyOb.vx = -game.maxV;
         EndIf
         If (MyOb.vy>game.maxV)
            MyOb.vy = game.maxV;
         Else If (MyOb.vy<-game.maxV)
            MyOb.vy = -game.maxV;
         EndIf
         ' update the vector parameters
         myob.updateObject();
         ' check the walls For collisions
         For w = EachIn game.Walllist
            ' If we have hit the wall
            pen# = MyOb.r-myOb.findIntersection(w);
            If pen>=0 
               ' move MyObject away from the wall
               MyOb.p1.x :+ w.lx*pen;
               MyOb.p1.y :+ w.ly*pen;
               ' change movement
               vb = myob.bounce(w);
               MyOb.vx = vb.vx;
               MyOb.vy = vb.vy;
            EndIf
         Next
         ' reset MyObject To other side If gone out of stage
         If (MyOb.p1.x>game.stageW+MyOb.r)
            MyOb.p1.x = -Myob.r;
         ElseIf (Myob.p1.x<-Myob.r)
            MyOb.p1.x = game.stageW+Myob.r;
         EndIf
         If (Myob.p1.y>game.stageH+Myob.r)
            MyOb.p1.y = -Myob.r;
         ElseIf (Myob.p1.y<-Myob.r)
            MyOb.p1.y = game.stageH+Myob.r;
         EndIf
         ' draw it
         drawAll(Myob);
         ' make End point equal To starting point For Next cycle
         MyOb.p0 = MyOb.p1;
         ' save the movement without time
         MyOb.vx :/ MyOb.timeFrame;
         MyOb.vy :/ MyOb.timeFrame;
      End Method
			
	  Method drawall(v1:vector2d)
		For Local v:vector2d = EachIn game.Walllist
			DrawLine v.p0.x,v.p0.y,v.p1.x,v.p1.y
		Next
		DrawOval v1.p0.x-v1.r,v1.p0.y-v1.r,..
		         v1.r*2,v1.r*2
	  End Method
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#
	Field r#
	Global airf#
	Global b#
	Global f#
    
	Method updateObject()
         Local ThisTime#,time#
		 ' find time passed from last update
         thisTime = MilliSecs();
         time = (thisTime - lastTime) /100
         ' we use time, Not frames To move so multiply movement vector with time passed
         vx :* time;
         vy :* time;
         ' add gravity, also based on time
         vy = vy+time*game.gravity;
         p1 = New point;
         ' find End point coordinates
         p1.x = p0.x+vx;
         p1.y = p0.y+vy;
         ' length of vector
         Length = Sqr(vx*vx+vy*vy);
         ' normalized unti-sized components
         dx = vx/Length;
         dy = vy/Length;
         ' Right hand normal
         rx = -vy;
         ry = vx;
         ' Left hand normal
         lx = vy;
         ly = -vx;
         ' save the current time
         lastTime = thisTime;
         ' save time passed
         timeFrame = time;
      End Method
	
      Method updateVector:vector2d()
         ' x And y components
         ' End point coordinate - start point coordinate
         vx = p1.x-p0.x
         vy = p1.y-p0.y
         ' length of vector
         Length = Sqr(vx*vx+vy*vy);
         ' normalized unti-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;
         Return Self
      End Method
      ' find New vector bouncing from v2
      Method bounce:vector2d(v2:vector2d)
         ' projection of v1 on v2
         Local proj1:vector2d = projectVector(Self, v2.dx, v2.dy);
         ' projection of v1 on v2 normal
         Local proj2:vector2d = projectVector(Self, v2.lx, v2.ly);
         Local proj:vector2d = New vector2d
         ' reverse projection on v2 normal
         proj2.Length = Sqr(proj2.vx*proj2.vx+proj2.vy*proj2.vy);
         proj2.vx = v2.lx*proj2.Length
         proj2.vy = v2.ly*proj2.Length
         ' add the projections
         proj.vx = f*v2.f*proj1.vx+b*v2.b*proj2.vx
         proj.vy = f*v2.f*proj1.vy+b*v2.b*proj2.vy
         Return proj
      End Method
      ' project vector v1 on unit-sized vector dx/dy
      Method 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 Method
      ' find intersection point of 2 vectors
      Method findIntersection# (v2:vector2d)
         ' vector between center of ball And starting point of wall
         Local v3:vector2d = New vector2d
		 
         v3.vx = p1.x-v2.p0.x;
         v3.vy = p1.y-v2.p0.y;
         ' project this vector on the normal of the wall
         Local v:vector2d = projectVector(v3, v2.lx, v2.ly);
         ' find length of projection
         v.Length = Sqr(v.vx*v.vx+v.vy*v.vy);
         Return v.Length;
      End Method
End Type

Global game:tgame = New tgame
' Create gameMyObject
' CreateMyObject
' point p0 is its starting point in the coordinates x/y
game.Create(640,480,20,0.6)
      game.myOb.airf = 1.0
	  game.myOb.b = 0.5
	  game.myOb.f = 0.9
	  game.myOb.r = 20
	  game.MyOb.lastTime = MilliSecs()
      game.myOb.p0 = New point
	  game.myOb.p0.x = 350
	  game.myOb.p0.y = 120
      ' vectors x/y components
      game.myOb.vx = 0;
      game.myOb.vy = -25;
      Local v:vector2d = New vector2d
	  game.createWall(600,50,50,50,1,1)
	  game.createWall(250,450,600,50,1,1)
	  game.createWall(50,450,250,450,1,1)
	  game.createWall(50,50,50,450,1,1)


Graphics game.stageW,game.stageH
Repeat
	Cls
	game.animate()
	game.drawall(game.myob)
	Flip()
Until KeyDown(key_escape)

Comments

None.

Code Archives Forum