2 dimensional bounding boxes

Community Forums/Showcase/2 dimensional bounding boxes

SSS(Posted 2004) [#1]
i dunno if this will be of any use to anyone, just made it for fun in like 30 mins this morning cuz i wanted to use matrices manualy (dunno why :P). But yea here it is 2 dimensional bounding box code, they can be rotated scaled positioned drawn and of course intercected for collisions...

;Matrix Codes
Const MATRIX_ALL = 0000
Const MATRIX_TRANSLATION = 0001
Const MATRIX_ROTATION = 0002
Const MATRIX_SCALE = 0003

;Bounding Box Type
Type BBox2D
	Field x1,y1
	Field x2,y2
	Field x3,y3
	Field x4,y4
	Field PosMat.Matrix2D
	Field RotMat.Matrix2D
	Field ScaleMat.Matrix2D
End Type

;Matrix Type
Type Matrix2D
	Field v00#,v10#,v20#,v01#,v11#,v21#,v02#,v12#,v22#
End Type


;function to create a 2d bounding box
Function CreateBBox2D(x1,y1,x2,y2)
	b.BBox2D = New BBox2D
	b\PosMat = New Matrix2D
	b\RotMat = New Matrix2D
	b\ScaleMat = New Matrix2D
	b\x1 = x1
	b\y1 = y1
	b\x2 = x2
	b\y2 = y1
	b\x3 = x2
	b\y3 = y2
	b\x4 = x1
	b\y4 = y2
	ResetBBox2DMatrix(Handle(b),0000)
	Return Handle(b)
End Function 

;function to position a bounding box
Function PositionBBox2D(h,x,y)
	b.BBox2D = Object.BBox2D(h)
	SetBBox2DMatrix(b\PosMat,1,0,x,0,1,y,0,0,1)
End Function

;function to rotate a bounding box
Function RotateBBox2D(h,angle#)
	b.BBox2D = Object.BBox2D(h)
	SetBBox2DMatrix(b\RotMat,Cos(angle#),Sin(angle#),0,-Sin(angle#),Cos(angle#),0,0,0,1)
End Function

;function to scale a bounding box
Function ScaleBBox2D(h,sx,sy)
	b.BBox2D = Object.BBox2D(h)
	SetBBox2DMatrix(b\ScaleMat,sx,0,0,0,sy,0,0,0,1)
End Function

;funciton to draw bounding boxes
Function DrawBBox2D(h)
	b.BBox2D = Object.BBox2D(h)
	Matrix.Matrix2D = New Matrix2D
	SetBBox2DMatrix(Matrix,b\RotMat\v00,b\RotMat\v10,b\PosMat\v20,b\RotMat\v01,b\RotMat\v11,b\PosMat\v21,0,0,1)
	MultBBox2DMatrix(Matrix,b\ScaleMat\v00,0,0,0,b\ScaleMat\v11,0,0,0,1)
	vx1 = b\x1*Matrix\v00 + b\y1*Matrix\v10 + Matrix\v20
	vy1 = b\x1*Matrix\v01 + b\y1*Matrix\v11 + Matrix\v21
	vx2 = b\x2*Matrix\v00 + b\y2*Matrix\v10 + Matrix\v20
	vy2 = b\x2*Matrix\v01 + b\y2*Matrix\v11 + Matrix\v21
	vx3 = b\x3*Matrix\v00 + b\y3*Matrix\v10 + Matrix\v20
	vy3 = b\x3*Matrix\v01 + b\y3*Matrix\v11 + Matrix\v21
	vx4 = b\x4*Matrix\v00 + b\y4*Matrix\v10 + Matrix\v20
	vy4 = b\x4*Matrix\v01 + b\y4*Matrix\v11 + Matrix\v21
	Line vx1,vy1,vx2,vy2
	Line vx2,vy2,vx3,vy3
	Line vx3,vy3,vx4,vy4
	Line vx4,vy4,vx1,vy1
	Delete Matrix
End Function

;function to test for intercections between bounding boxes
Function BBoxesIntersect(hb1,hb2)
	b1.BBox2D = Object.BBox2D(hb1)
	Matrix.Matrix2D = New Matrix2D
	SetBBox2DMatrix(Matrix,b1\RotMat\v00,b1\RotMat\v10,b1\PosMat\v20,b1\RotMat\v01,b1\RotMat\v11,b1\PosMat\v21,0,0,1)
	MultBBox2DMatrix(Matrix,b1\ScaleMat\v00,0,0,0,b1\ScaleMat\v11,0,0,0,1)
	vx11 = b1\x1*Matrix\v00 + b1\y1*Matrix\v10 + Matrix\v20
	vy11 = b1\x1*Matrix\v01 + b1\y1*Matrix\v11 + Matrix\v21
	vx12 = b1\x2*Matrix\v00 + b1\y2*Matrix\v10 + Matrix\v20
	vy12 = b1\x2*Matrix\v01 + b1\y2*Matrix\v11 + Matrix\v21
	vx13 = b1\x3*Matrix\v00 + b1\y3*Matrix\v10 + Matrix\v20
	vy13 = b1\x3*Matrix\v01 + b1\y3*Matrix\v11 + Matrix\v21
	vx14 = b1\x4*Matrix\v00 + b1\y4*Matrix\v10 + Matrix\v20
	vy14 = b1\x4*Matrix\v01 + b1\y4*Matrix\v11 + Matrix\v21
	
	b2.BBox2D = Object.BBox2D(hb2)
	SetBBox2DMatrix(Matrix,b2\RotMat\v00,b2\RotMat\v10,b2\PosMat\v20,b2\RotMat\v01,b2\RotMat\v11,b2\PosMat\v21,0,0,1)
	MultBBox2DMatrix(Matrix,b2\ScaleMat\v00,0,0,0,b2\ScaleMat\v11,0,0,0,1)
	vx21 = b2\x1*Matrix\v00 + b2\y1*Matrix\v10 + Matrix\v20
	vy21 = b2\x1*Matrix\v01 + b2\y1*Matrix\v11 + Matrix\v21
	vx22 = b2\x2*Matrix\v00 + b2\y2*Matrix\v10 + Matrix\v20
	vy22 = b2\x2*Matrix\v01 + b2\y2*Matrix\v11 + Matrix\v21
	vx23 = b2\x3*Matrix\v00 + b2\y3*Matrix\v10 + Matrix\v20
	vy23 = b2\x3*Matrix\v01 + b2\y3*Matrix\v11 + Matrix\v21
	vx24 = b2\x4*Matrix\v00 + b2\y4*Matrix\v10 + Matrix\v20
	vy24 = b2\x4*Matrix\v01 + b2\y4*Matrix\v11 + Matrix\v21

	
	If LinesIntersect(vx11,vy11,vx12,vy12,vx21,vy21,vx22,vy22) Then Return True
	If LinesIntersect(vx11,vy11,vx12,vy12,vx22,vy22,vx23,vy23) Then Return True
	If LinesIntersect(vx11,vy11,vx12,vy12,vx23,vy23,vx24,vy24) Then Return True
	If LinesIntersect(vx11,vy11,vx12,vy12,vx24,vy24,vx21,vy21) Then Return True
	
	If LinesIntersect(vx12,vy12,vx13,vy13,vx21,vy21,vx22,vy22) Then Return True
	If LinesIntersect(vx12,vy12,vx13,vy13,vx22,vy22,vx23,vy23) Then Return True
	If LinesIntersect(vx12,vy12,vx13,vy13,vx23,vy23,vx24,vy24) Then Return True
	If LinesIntersect(vx12,vy12,vx13,vy13,vx24,vy24,vx21,vy21) Then Return True
	
	If LinesIntersect(vx13,vy13,vx14,vy14,vx21,vy21,vx22,vy22) Then Return True
	If LinesIntersect(vx13,vy13,vx14,vy14,vx22,vy22,vx23,vy23) Then Return True
	If LinesIntersect(vx13,vy13,vx14,vy14,vx23,vy23,vx24,vy24) Then Return True
	If LinesIntersect(vx13,vy13,vx14,vy14,vx24,vy24,vx21,vy21) Then Return True
	
	If LinesIntersect(vx14,vy14,vx11,vy11,vx21,vy21,vx22,vy22) Then Return True
	If LinesIntersect(vx14,vy14,vx11,vy11,vx22,vy22,vx23,vy23) Then Return True
	If LinesIntersect(vx14,vy14,vx11,vy11,vx23,vy23,vx24,vy24) Then Return True
	If LinesIntersect(vx14,vy14,vx11,vy11,vx24,vy24,vx21,vy21) Then Return True
	
	Return False
End Function
	
;function to check for line to line intersections
Function LinesIntersect(x11,y11,x12,y12,x21,y21,x22,y22)
	If x11=x12 Then x12 = x12+1
	If x21=x22 Then x22 = x22+1
	If y11=y12 Then y12 = y12+1
	If y21=y22 Then y22 = y22+1
	m1# = Float#((y12-y11))/Float#((x12-x11))
	c1# = Float#(y11)-m1#*Float#(x11)
	m2# = Float#((y22-y21))/Float#((x22-x21))
	c2# = Float#(y21)-m2#*Float#(x21)
	x# = Float#(c2#-c1#)/Float#(m1#-m2#)
	y# = m1#*x#+c1#
	If x11>x12
		temp = x11
		x11 = x12
		x12 = temp 
	EndIf
	If y11>y12
		temp = y11
		y11 = y12
		y12 = temp 
	EndIf
	If x21>x22
		temp = x21
		x21 = x22
		x22 = temp 
	EndIf
	If y21>y22
		temp = y21
		y21 = y22
		y22 = temp 
	EndIf
	If Int(x#)>=x11 And Int(x#)<=x12 And Int(y#)>=y11 And Int(y#)<=y12 And Int(x#)>=x21 And Int(x#)<=x22 And Int(y#)>=y21 And Int(y#)<=y22
		Return True
	EndIf
		Return False
End Function

;function to reset bounding box matrixes
Function ResetBBox2DMatrix(h,matrix)
	b.BBox2D = Object.BBox2D(h)
	Select(matrix)
		Case 0000:
			SetBBox2DMatrix(b\PosMat,1,0,0,0,1,0,0,0,1)
			SetBBox2DMatrix(b\RotMat,1,0,0,0,1,0,0,0,1)
			SetBBox2DMatrix(b\ScaleMat,1,0,0,0,1,0,0,0,1)
		Case 0001:
			SetBBox2DMatrix(b\PosMat,1,0,0,0,1,0,0,0,1)
		Case 0002:
			SetBBox2DMatrix(b\RotMat,1,0,0,0,1,0,0,0,1)
		Case 0003:
			SetBBox2DMatrix(b\ScaleMat,1,0,0,0,1,0,0,0,1)
		Default:
			MessageBox("Error","Error: Incorrect Matrix Selection (ResetBBox2DMatrix)")
	End Select 
End Function

;function to Set a bounding boxes matrix
Function SetBBox2DMatrix(mat.Matrix2D,v00#,v10#,v20#,v01#,v11#,v21#,v02#,v12#,v22#)
	mat\v00 = v00#
	mat\v10 = v10#
	mat\v20 = v20#
	mat\v01 = v01#
	mat\v11 = v11#
	mat\v21 = v21#
	mat\v02 = v02#
	mat\v12 = v12#
	mat\v22 = v22#
End Function 

;function to multiply matrices
Function MultBBox2DMatrix(mat.Matrix2D,v00#,v10#,v20#,v01#,v11#,v21#,v02#,v12#,v22#)
	mat\v00 = mat\v00*v00# + mat\v10*v01# + mat\v20*v02#
	mat\v10 = mat\v00*v10# + mat\v10*v11# + mat\v20*v12#
	mat\v20 = mat\v00*v20# + mat\v10*v21# + mat\v20*v22#
	mat\v01 = mat\v01*v00# + mat\v11*v01# + mat\v21*v02#
	mat\v11 = mat\v01*v10# + mat\v11*v11# + mat\v21*v12#
	mat\v21 = mat\v01*v20# + mat\v11*v21# + mat\v21*v22#
	mat\v02 = mat\v02*v00# + mat\v12*v01# + mat\v22*v02#
	mat\v12 = mat\v02*v10# + mat\v12*v11# + mat\v22*v12#
	mat\v22 = mat\v02*v20# + mat\v12*v21# + mat\v22*v22#
End Function 

;function to equate two matrices
Function EquateBBox2DMatrices(mat1.Matrix2D,mat2.Matrix2D)
	mat1\v00 =mat2\v00#
	mat1\v10 =mat2\v10#
	mat1\v20 =mat2\v20#
	mat1\v01 =mat2\v01#
	mat1\v11 =mat2\v11#
	mat1\v21 =mat2\v21#
	mat1\v02 =mat2\v02#
	mat1\v12 =mat2\v12#
	mat1\v22 =mat2\v22#
End Function 


here's a small example

include "BBox2D.bb"
Graphics 640,480,32,2
SetBuffer BackBuffer()

;create two Bounding Box with the cordinates -20 to 20 on both the x and y
b = CreateBBox2D(-20,-20,20,20)
c = CreateBBox2D(-20,-20,20,20)

Color 0,255,0
;enlarge one of the bounding boxes
ScaleBBox2D b, 2,2
;position the bounding boxes
PositionBBox2D b, 205,205
PositionBBox2D c, 250,250
angle# = 0
angle2# = 0
While Not KeyDown(1)
	Cls
	;rotate the bounding boxes by the angles
	RotateBBox2D(b,angle#)
	RotateBBox2D(c,angle2#)
	Color 0,255,0
	;Draw The Bounding Boxes
	DrawBBox2D(b)
	DrawBBox2D(c)
	;Check for an intersection
	If BBoxesIntersect(b,c) Then Text 10,10,"INTERSECTION"
	;Rotate the bounding boxes
	angle# = angle# + 0.5
	angle2# = angle# +0.7
	Flip
Wend


if you have any questions feel free to ask