

--[[---------------------------------------------------------

   Name: Dist( low, high )

   Desc: Distance between two 2d points

------------------------------------------------------------]]

function math.Dist( x1, y1, x2, y2 )

	local xd = x2-x1

	local yd = y2-y1

	return math.sqrt( xd*xd + yd*yd )

end



math.Distance = math.Dist -- alias





--[[---------------------------------------------------------

   Name: BinToInt( bin )

   Desc: Convert a binary string to an integer number

------------------------------------------------------------]]

function math.BinToInt(bin)

	return tonumber(bin,2)

end





--[[---------------------------------------------------------

   Name: IntToBin( int )

   Desc: Convert an integer number to a binary string

------------------------------------------------------------]]

function math.IntToBin(int)



	local str = string.format("%o",int)



	local a = {

			["0"]="000",["1"]="001", ["2"]="010",["3"]="011",

        		["4"]="100",["5"]="101", ["6"]="110",["7"]="111"

		  }

	local bin = string.gsub( str, "(.)", function ( d ) return a[ d ] end )

	return bin



end



--[[---------------------------------------------------------

   Name: Clamp( in, low, high )

   Desc: Clamp value between 2 values

------------------------------------------------------------]]

function math.Clamp( _in, low, high )

	if (_in < low ) then return low end

	if (_in > high ) then return high end

	return _in

end



--[[---------------------------------------------------------

   Name: Rand( low, high )

   Desc: Random number between low and high

-----------------------------------------------------------]]

function math.Rand( low, high )

	return low + ( high - low ) * math.random()

end



--[[---------------------------------------------------------

    math.Max, alias for math.max

-----------------------------------------------------------]]

math.Max = math.max



--[[---------------------------------------------------------

   math.Min, alias for math.min

-----------------------------------------------------------]]

math.Min = math.min



--[[---------------------------------------------------------

    Name: EaseInOut(fProgress, fEaseIn, fEaseOut)

    Desc: Provided by garry from the facewound source and converted

          to Lua by me :p

   Usage: math.EaseInOut(0.1, 0.5, 0.5) - all parameters shoule be between 0 and 1

-----------------------------------------------------------]]

function math.EaseInOut( fProgress, fEaseIn, fEaseOut ) 



	if (fEaseIn == nil) then fEaseIn = 0 end

	if (fEaseOut == nil) then fEaseOut = 1 end



	local fSumEase = fEaseIn + fEaseOut; 



	if( fProgress == 0.0 || fProgress == 1.0 ) then return fProgress end



	if( fSumEase == 0.0 ) then return fProgress end

	if( fSumEase > 1.0 ) then

		fEaseIn = fEaseIn / fSumEase; 

		fEaseOut = fEaseOut / fSumEase; 

	end



	local fProgressCalc = 1.0 / (2.0 - fEaseIn - fEaseOut); 



	if( fProgress < fEaseIn ) then

		return ((fProgressCalc / fEaseIn) * fProgress * fProgress); 

	elseif( fProgress < 1.0 - fEaseOut ) then

		return (fProgressCalc * (2.0 * fProgress - fEaseIn)); 

	else 

		fProgress = 1.0 - fProgress; 

		return (1.0 - (fProgressCalc / fEaseOut) * fProgress * fProgress); 

	end

end





--[[------------------------------------

	KNOT()

--------------------------------------]]

local function KNOT( i, tinc )



	return ( i - 3 ) * tinc;

	

end





--[[------------------------------------

	math.calcBSplineN()

--------------------------------------]]

function math.calcBSplineN( i, k, t, tinc )



	if ( k == 1 ) then

	

		if ( ( KNOT( i, tinc ) <= t ) && ( t < KNOT( i + 1, tinc ) ) ) then

		

			return 1;

			

		else

		

			return 0;

			

		end

		

	else

		local ft = ( t - KNOT( i, tinc ) ) * math.calcBSplineN( i, k - 1, t, tinc );

		local fb = KNOT( i + k - 1, tinc ) - KNOT( i, tinc );



		local st = ( KNOT( i + k, tinc ) - t ) * math.calcBSplineN( i + 1, k - 1, t, tinc );

		local sb = KNOT( i + k, tinc ) - KNOT( i + 1, tinc );

		

		local first = 0;

		local second = 0;



		if ( fb > 0 ) then

		

			first = ft / fb;

			

		end

		if ( sb > 0 ) then

		

			second = st / sb;

			

		end



		return first + second;

		

	end

	

end





--[[------------------------------------

	math.BSplinePoint()

--------------------------------------]]

function math.BSplinePoint( tDiff, tPoints, tMax )

	

	local Q = Vector( 0, 0, 0 );

	local tinc = tMax / ( table.getn( tPoints ) - 3 );

	

	tDiff = tDiff + tinc;

	

	for idx, pt in pairs( tPoints ) do

	

		local n = math.calcBSplineN( idx, 4, tDiff, tinc );

		Q = Q + (n * pt);

		

	end

	

	return Q;

	

end







--[[---------------------------------------------------------

    Name: Round( round )

-----------------------------------------------------------]]

function math.Round(num, idp)



	local mult = 10^(idp or 0)

	return math.floor(num * mult + 0.5) / mult

  

end



--[[---------------------------------------------------------

    Name: Approach( cur, target, inc )

-----------------------------------------------------------]]

function math.Approach( cur, target, inc )



	inc = math.abs( inc )



	if (cur < target) then

		

		return math.Clamp( cur + inc, cur, target )



	elseif (cur > target) then



		return math.Clamp( cur - inc, target, cur )



	end



	return target

	

end



function math.NormalizeAngle( a )

	return ( a + 180 ) % 360 - 180

end





function math.AngleDifference( a, b )



	local diff = math.NormalizeAngle( a - b )

	

	if ( diff < 180 ) then

		return diff

	end

	

	return diff - 360



end



--[[---------------------------------------------------------

    Name: ApproachAngle( cur, target, inc )

-----------------------------------------------------------]]

function math.ApproachAngle( cur, target, inc )



	local diff = math.AngleDifference( target, cur )

	

	return math.Approach( cur, cur + diff, inc )

	

end



--[[---------------------------------------------------------

    Name: TimeFraction( Start, End, Current )

-----------------------------------------------------------]]

function math.TimeFraction( Start, End, Current )

	return ( Current - Start ) / ( End - Start )

end



--[[---------------------------------------------------------

    Name: Remap( value, inMin, inMax, outMin, outMax )

-----------------------------------------------------------]]

function math.Remap( value, inMin, inMax, outMin, outMax )

	return outMin + ( ( ( value - inMin ) / ( inMax - inMin ) ) * ( outMax - outMin ) )

end

