polygon collision

BlitzMax Forums/BlitzMax Beginners Area/polygon collision

Got some BMax code for you:

SuperStrict

' Vector type ( A VERY SIMPLE VECTOR TYPE )
Type TVector
	
	Field x#, y#
	
	Function Create:TVector(_x#, _y#)
		Local v:TVector = New TVector
		v.x = _x
		v.y = _y
		Return v
	End Function
	
	Method DivEq(_scale#)
		x:/ _scale
		y:/ _scale
	End Method
	
	Method MulEq(_scale#)
		x:* _scale
		y:* _scale
	End Method
	
	Method AddEq(v:TVector)
		x:+ v.x
		y:+ v.y
	End Method
	
	Method MinEq(v:TVector)
		x:- v.x
		y:- v.y
	End Method
	
	Method CrossProduct#(v:TVector)
		Return x * v.y - y * v.x
	End Method
	
	Method Dot#(v:TVector)
		Return x * v.x + y * v.y
	End Method
	
	Method Mul:TVector(_scale#)
		Return TVector.Create(x * _scale, y * _scale)
	End Method
	
	Method Div:TVector(_scale#)
		Return TVector.Create(x / _scale, y / _scale)
	End Method
	
	Method Add:TVector(v:TVector)
		Return TVector.Create(x + v.x, y + v.y)
	End Method
	
	Method Sub:TVector(v:TVector)
		Return TVector.Create(x - v.x, y - v.y)
	End Method
	
	Method Leng#()
		Return Sqr(x * x + y * y)
	End Method

	rem
		Do two vectors intersect along a given axis
	endrem
	Function Intersect@(a:TVector[], b:TVector[], xa:TVector, _offset:TVector)
	
		Local min0#, max0#
		Local min1#, max1#
		
		min0 = IntervalMin(a, xa)
		max0 = IntervalMax(a, xa)
		min1 = IntervalMin(b, xa)
		max1 = IntervalMax(b, xa)
		
		Local h# = _offset.Dot(xa)
		min0:+ h
		max0:+ h
		
		Local d0# = min0 - max1
		Local d1# = min1 - max0
		
		If d0 > 0.0 or d1 > 0.0 Then
			Return False
		Else
			Return True
		End If
	
	End Function
	
	rem
		Min / Max functions
		nothing sepcial
	endrem
	Function IntervalMin#(verts:TVector[], xa:TVector)
		Local m# = verts[0].Dot(xa)
		
		For Local i% = 0 To verts.length - 1
			Local d# = verts[i].Dot(xa)
			If d < m Then m = d
		Next
		
		Return m
	End Function
	
	Function IntervalMax#(verts:TVector[], xa:TVector)
		Local m# = verts[0].Dot(xa)
		
		For Local i% = 0 To verts.length - 1
			Local d# = verts[i].Dot(xa)
			If d > m Then m = d
		Next
		
		Return m
	End Function
	
End Type

' A simple polygon type
Type TPolygon
	
	Field x#, y# 	' Draw offset
	Field vx#[]		' Zero Based
	Field vy#[]		' Zero based
	Field vc#		' Vertex Count
	
	' Just to help
	Function CreateByVectorList:TPolygon(_v:TList)
		Local p:TPolygon = New TPolygon
		p.vx = New Float[_v.count()]
		p.vy = New Float[_v.count()]
		p.vc = _v.count()
		
		Local i% = 0
		For Local v:TVector = EachIn _v
			
			p.vx[i] = v.x
			p.vy[i] = v.y

			i:+ 1
		Next
		Return p
	End Function
	
	' Draw it
	Method Render()
		SetColor 255, 0, 0
		
		Local _vx#[2], _vy#[2]
		For Local i% = 0 To vc - 2
			_vx[0] = vx[i] + x
			_vy[0] = vy[i] + y
			_vx[1] = vx[i + 1] + x
			_vy[1] = vy[i + 1] + y
			DrawLine _vx[0], _vy[0], _vx[1], _vy[1]
		Next
		
		_vx[0] = vx[vc - 1] + x
		_vy[0] = vy[vc - 1] + y
		_vx[1] = vx[0] + x
		_vy[1] = vy[0] + y
		DrawLine _vx[0], _vy[0], _vx[1], _vy[1]
		SetColor 0, 0, 0
	End Method
	
	' Set position
	Method SetPos(_x%, _y%)
		x = _x
		y = _y
	End Method
	
	' Test Collide _offset you shouldnt need to worry about but just incase...
	Method Collide@(p:TPolygon, _offset:TVector = Null)
		
		SetColor 0, 255, 0
		If _offset = Null Then
			_offset = TVector.Create(x, y).Sub(TVector.Create(p.x, p.y))
		End If
		
		Local a:TVector[], b:TVector[]
		Local i%
		
		a = New TVector[vc]
		For i = 0 To vc - 1
			a[i] = New TVector
			a[i].x = vx[i]
			a[i].y = vy[i]
		Next
		
		b = New TVector[p.vc]
		For i = 0 To p.vc - 1
			b[i] = New TVector
			b[i].x = p.vx[i]
			b[i].y = p.vy[i]
		Next
		
		Local xv:TVector[64]
		Local ai% = 0
		
		Local j% = vc - 1
		For Local i% = 0 To vc - 1
			Local e0:TVector = a[j]
			Local e1:TVector = a[i]
			Local e:TVector = e1.Sub(e0)
			xv[ai] = TVector.Create(-e.y, e.x)
			
			If not TVector.Intersect(a, b, xv[ai], _offset)
				Return False
			EndIf
			
			j = i
			ai:+ 1
		Next
		
		j% = p.vc - 1
		For Local i% = 0 To p.vc - 1
			Local e0:TVector = b[j]
			Local e1:TVector = b[i]
			Local e:TVector = e1.Sub(e0)
			xv[ai] = TVector.Create(-e.y, e.x)
			
			If not TVector.Intersect(a, b, xv[ai], _offset)
				Return False
			EndIf
			
			j = i
			ai:+ 1
		Next
		
		Return True
		
	End Method
	
End Type

Local Box:TList = CreateList()
Box.AddLast(TVector.Create(0, 0))
Box.AddLast(TVector.Create(100, 0))
Box.AddLast(TVector.Create(100, 100))
Box.AddLast(TVector.Create(0, 100))
Local Shape:TList = CreateList()
Shape.AddLast(TVector.Create(25, 0))
Shape.AddLast(TVector.Create(50, 0))
Shape.AddLast(TVector.Create(75, 25))
Shape.AddLast(TVector.Create(50, 50))
Shape.AddLast(TVector.Create(25, 50))
Shape.AddLast(TVector.Create(0, 25))
Global ap1:TPolygon = TPolygon.CreateByVectorList(Box)
ap1.SetPos(200, 200)
Global ap2:TPolygon = TPolygon.CreateByVectorList(Shape)
ap2.SetPos(100, 100)

Graphics 800, 600

While not KeyHit(KEY_ESCAPE)
	
	Cls
	
	ap2.SetPos(MouseX(), MouseY())
	ap1.Render()
	ap2.Render()
	
	SetColor 255, 255, 255
	If ap2.Collide(ap1) Then DrawText "COLLIDED!!!", 10, 10
	
	Flip 0
	
Wend


The code is a quick ripp from This Good Chap

Edit: It dosent always work the way you might want it to but i'll leave you to experiment. The above link has got a link to download a .zip with some code in it. (cpp source)