
--should these be local and declared per script?
sin, cos, abs, mod, floor, pow, sqrt = math.sin, math.cos, math.abs, math.mod, math.floor, math.pow, math.sqrt
min, max = math.min, math.max
atan2 = math.atan2
insert = table.insert

math.randomseed( os.time() )
math.random();  math.random();  math.random();	--first few numbers aren't really random :O

random = math.random

PI = 3.141529
PIhalf = .5 * PI
PI2 = 2. * PI

function HSLA(h, s, v, a)
 
  local r, g, b
 
  local i = math.floor(h * 6)
  local f = h * 6 - i
  local p = v * (1 - s)
  local q = v * (1 - f * s)
  local t = v * (1 - (1 - f) * s)
 
  local switch = i % 6
  if switch == 0 then
    r = v g = t b = p
  elseif switch == 1 then
    r = q g = v b = p
  elseif switch == 2 then
    r = p g = v b = t
  elseif switch == 3 then
    r = p g = q b = v
  elseif switch == 4 then
    r = t g = p b = v
  elseif switch == 5 then
    r = v g = p b = q
  end
 Color( r, g, b, a )
 -- return math.floor(r), math.floor(g), math.floor(b)
--	return r, g, b
end

function ucos( v )
	return cos( PI * v )
end

function usin( v )
	return sin( PI * v )
end

function distance2( v1, v2 )
	
	dis0 = v1[ 1 ] - v2[ 1 ]
	dis1 = v1[ 2 ] - v2[ 2 ]
	return sqrt( dis0 * dis0 + dis1 * dis1 )
	
end

function randint( low, high )
	return low + math.floor( math.random() * ( high + .999 - low ) )
end

function rand( low, high )
	low = low or 0
	high = high or 1
	return low + ( math.random() * ( high - low ) )
end

function clamp( val, a, b )
	if ( val < a ) then return a end
	if ( val > b ) then return b end
	return val
end

function limit( a, b, val )
	if ( val < a ) then return a end
	if ( val > b ) then return b end
	return val
end

--Gets distance from a 2d point to an infinite 2d line (a and b can be anywhere along line)
function PointLineDistance2( inLineA, inLineB, inPt )
	xa = inLineA[ 1 ]
	ya = inLineA[ 2 ]
	xb = inLineB[ 1 ]
	yb = inLineB[ 2 ]
	xc = inPt[ 1 ]
	yc = inPt[ 2 ]
	
	return sqrt(((yb-ya)*(xc-xa)-(xb-xa)*(yc-ya))^2/((xb-xa)^2 + (yb-ya)^2))
end

function PointLineSegDistance2( inLineA, inLineB, inPt )
	x1 = inLineA[ 1 ]
	y1 = inLineA[ 2 ]
    x2 = inLineB[ 1 ]
	y2 = inLineB[ 2 ]
	x3 = inPt[ 1 ]
	y3 = inPt[ 2 ]
    px = x2 - x1
    py = y2 - y1

    dis2 = px * px + py * py

    u = (( x3 - x1 ) * px + ( y3 - y1 ) * py ) / dis2

    if u > 1 then
        u = 1
	elseif u < 0 then
        u = 0
	end

    x = x1 + u * px
    y = y1 + u * py

    dx = x - x3
    dy = y - y3

    return sqrt( dx * dx + dy * dy )

end
	
function normalize2( val )
	low = 0.00001
	local dist = max( low, sqrt( val[ 2 ] * val[ 2 ] + val[ 1 ] * val[ 1 ] ) )
	if ( dist <= low ) then
		val[ 1 ] = low
	end
	nVal = { val[ 1 ] / dist, val[ 2 ] / dist }
	
	return nVal, dist
end

function sign(x)
	if x<0 then
		return -1
	else
		return 1
	end
end
