Elipsoid Collision detection, But...

BlitzMax Forums/BlitzMax Programming/Elipsoid Collision detection, But...

Edit: Final Vertions of the Files you will need to run the example.
The files you will need.

Save as Vector.Bmx this Vector type posted by SSS in the MaxPhysics topic.
'Strict
'Import BRL.Basic
Type TVector
	'VARIABLES
	Field _x:Double, _y:Double
	
	'METHODS
	Method New()
		_x = 0
		_y = 0
	End Method
	
	Method Set(x:Double,y:Double)
		_x=x
		_y=y
	End Method
	
	Method Get(x:Double Var, y:Double Var)
		x = _x
		y = _y
	End Method
	
	Method Multiply:TVector(factor:Double , bSelf:Byte = True)
		If bSelf = False
			Return TVector.create(_x*factor , _y*factor)
		Else	
			_x:*factor
			_y:*factor
			Return Self
		End If
	End Method
	
	Method Add:TVector(v:TVector,bself=False)
		If bself = False
			Return TVector.Create(_x+v._x,_y+v._y)
		Else
			_x:+v._x
			_y:+v._y
			Return Self 
		EndIf
	End Method
	
	Method Subtract:TVector(v:TVector,bself=False)
		If bself = False
			Return TVector.Create(_x-v._x,_y-v._y)
		Else
			_x:-v._x
			_y:-v._y
			Return Self
		EndIf
	End Method
	
	Method Copy:TVector()
		Return Create(_x,_y)
	End Method
	
	Method DotProduct:Double(v:TVector)
		Return _x*v._x+_y*v._y
	End Method
	
	Method AngleBetween:Double(v:TVector)
		Return ACos(DotProduct(v)/(Magnitude()*v.Magnitude()))
	EndMethod
	
	Method SetAngle(angle:Double)
		Local mag:Double = Magnitude()
		_x = Cos(angle)*mag
		_y = -Sin(angle)*mag
	End Method
	
	Method GetAngle:Double()
		Return ATan2(-_y,_x)
	End Method
	
	Method SetMagnitude(mag:Double)
		Normalise()
		_x:*mag
		_y:*mag
	End Method
	
	Method Magnitude:Double()
		Return Sqr(_x^2+_y^2)
	End Method
	
	Method MagSquared:Double()
		Return _x^2+_y^2
	End Method
	
	Method Normalise:TVector(bself:Byte=True)
		Local m:Double = Magnitude()
		If bself = False
			Return TVector.Create(_x/m,_y/m)
		Else
			_x:/m
			_y:/m
		EndIf
	End Method
	
	Method Normalize:TVector(bself:Byte = True)
		Local m:Double = Magnitude()
		If bself = False
			Return TVector.Create(-_y/m,_x/m)
		Else
			Local _tmpx:Double = _x
			_x = -_y/m
			_y = _tmpx/m
		End If
	End Method
	
	
	Method Reverse:TVector(bSelf:Byte = False)
		If bSelf = False
			Return TVector.create(-_x , -_y)
		Else
			_x = -_x
			_y = -_y
		End If
	End Method
		
	Method PrintVector()
		Print "(" + _x + "," + _y + ")"
	End Method
	
	Method Draw(xoff,yoff)
		DrawLine xoff,yoff,xoff+_x,yoff+_y
	End Method

	'FUNCTIONS
	Function Create:TVector(x:Double,y:Double)
		Local o:TVector = New TVector
		o._x=x
		o._y=y
		Return o
	End Function
	
	Function FromTo:TVector(v1:TVector,v2:TVector)
		Return Create(v2._x-v1._x,v2._y-v2._x)
	End Function
End Type


And Stuff.Bmx that contains Function's from the Document and some more things

Function intersect:Double(pOrigin:TVector , pNormal:TVector , rOrigin:TVector , rVector:TVector)
	Local d:Double = -pNormal.DotProduct(pOrigin)
	Local numer:Double = pNormal.DotProduct(rOrigin) + d
	Local denom:Double = pNormal.DotProduct(rVector)
	Return -(numer / denom)
End Function


Function closestPointOnTriangle:TVector(a:TVector , b:TVector , c:TVector , p:TVector)
	Local Rab:TVector = closestPointOnLine(a , b , p)
	Local Rbc:TVector = closestPointOnLine(b , c , p)
	Local Rca:TVector = closestPointOnLine(c , a , p)
	
	'''/// Return the closest point... how?
		'''' So I find the square distance from the point of lines to p
	Local RabM:Double =  (Rab._x - p._x)^2 + (Rab._y - p._y)^2 
	Local RbcM:Double = (Rbc._x - p._x)^2 + (Rbc._y - p._y)^2 
	Local RcaM:Double = (Rca._x - p._x)^2 + (Rca._y - p._y)^2
	
	If closestOfThree(RbcM , RabM , RcaM) Then Return Rbc
	If closestOfThree(RcaM , RbcM , RabM) Then Return Rca
	If closestOfThree(RabM , RbcM , RcaM) Then Return Rab

	Function closestOfThree:Byte(a:Double , b:Double , c:Double)
		If a < b And a < c Then Return True
		If a = b And a < c Then Return True
		If a < b And a = c Then Return True
		Return False
	End Function
End Function

Function closestPointOnPolygon:TVector(_Pol:TPolygon , p:TVector)
	Local Rabc:TVector = closestPointOnTriangle(_Pol._p[0] , _Pol._p[1] , _Pol._p[2] , p)
	Local Rcda:TVector = closestPointOnTriangle(_Pol._p[2] , _Pol._p[3] , _Pol._p[0] , p)
	
	Local RabcM:Double = (Rabc._x - p._x)^2 + (Rabc._y - p._y)^2 
	Local RcdaM:Double = (Rcda._x - p._x)^2 + (Rcda._y - p._y)^2 
	
	If RabcM <= RcdaM Then Return Rabc Else Return Rcda
End Function



Function closestPointOnLine:TVector(a:TVector , b:TVector , p:TVector)
	Local c:TVector = TVector.create(p._x - a._x , p._y - a._y) '''' c = p - a
	Local V:TVector = TVector.create(b._x - a._x , b._y - a._y)  ''' V = b - a
	V.normalise()
	Local d:Double = Sqr( (a._x - b._x)^2 + (a._y - b._y)^2 )
	Local t:Double = V.dotProduct(c)
	
	''''// Check to see if 't' is beyond the extemnds of line segment
	If t < 0 Then Return a
	If t > d Then Return b
	
	''''///Return the point between 'a' and 'b'
	V.setMagnitude(t)
	Return TVector.create(a._x + V._x , a._y + V._y)
	
End Function

Function intersectSphere:Double(rO:TVector , rV:TVector , sO:TVector , sR:Double)
	Local rv2:TVector = rV.normalise(False)
	Local Q:TVector = TVector.create(sO._x - rO._x , sO._y - rO._y)
	Local c:Double = Q.Magnitude()
	Local v:Double = Q.DotProduct(rV2)
	Local d:Double = sR^2 - (c^2 - v^2)
	'''/// If there is no intersection Return -1
	If (d < 0.0) Return -1.0
	
	'' Return the distance to the [first] intersection point
	Return v - Sqr(d)
End Function

Function DrawCircle(_x:Double , _y:Double , _r:Double)
	DrawOval _x - _r , _y - _r , _r*2 , _r*2
End Function

Function DrawVectorCircle(_P:TVector , _r:Double)
	DrawOval _P._x - _r , _P._y - _r , _r*2 , _r*2
End Function

Function Mirror( Vector:TVector , Normal:TVector )
	Local Dotprod:Double = -Vector._X * Normal._X - Vector._Y * Normal._Y
	Vector._X=Vector._X+2 * Normal._X * dotprod
	Vector._Y=Vector._Y+2 * Normal._Y * dotprod
End Function

Function DivideVector:TVector(Source:TVector , Scaler:TVector , bSelf:Byte = True)
	If bSelf = False
		Return TVector.create(Source._x / Scaler._x , Source._y / Scaler._y)
	Else
		Source.set(Source._x / Scaler._x , Source._y / Scaler._y)
	End If
End Function

Function MultiplyVector:TVector(Source:TVector , Scaler:TVector , bSelf:Byte = True)
	If bSelf = False
		Return TVector.create(Source._x * Scaler._x , Source._y * Scaler._y)
	Else
		Source.set(Source._x * Scaler._x , Source._y * Scaler._y)
	End If
End Function


'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
'WWWWWWWWWWW   POLYGON
'WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
Type TPolygon
	Field _p:TVector[4]
	Global _List:TList = CreateList()
	
	Function createFromVectors:TPolygon(p1:TVector , p2:TVector , p3:TVector , p4:TVector)
		Local _Polygon:TPolygon = New TPolygon
		_Polygon._p[0] = p1.copy()
		_Polygon._p[1] = p2.copy()	
		_Polygon._p[2] = p3.copy()	
		_Polygon._p[3] = p4.copy()	
		ListAddLast _List , _Polygon
		Return _Polygon
	End Function
	
	Method draw()
		Local j:Int = 3
		For Local i:Int = 0 To 3
			DrawLine _p[j]._x , _p[j]._y , _p[i]._x , _p[i]._y
			DrawText i  , _p[i]._x , _p[i]._y 
			j = i
		Next
	End Method
End Type


That's all for now...