local d={}local D=.01 function d.Expt(b,P,q,B,y)if math.abs(q-P)<D then return q end local R=d:Expty(P,q,B,y)local m=(q-P)*R return P+m end function d.Expty(B,d,D,P,q)local y=1-P local b=-math.log(y)return 1-math.exp(-b*q)end function d.Sign(D,d)if d>0 then return 1 elseif d<0 then return-1 else return 0 end end function d.BezierValForT(y,d,D,P,q,B)local b=((1-B)*(1-B))*(1-B)local R=((3*B)*(1-B))*(1-B)local m=((3*B)*B)*(1-B)local l=(B*B)*B return((b*d+R*D)+m*P)+l*q end d._BezierPt2ForT={x=0,y=0}function d.BezierPt2ForT(S,D,P,q,B,y,b,R,m,l)d._BezierPt2ForT.x=d:BezierValForT(D,q,y,R,l)d._BezierPt2ForT.y=d:BezierValForT(P,B,b,m,l)return d._BezierPt2ForT end function d.YForPointOf2PtLine(q,d,D,P)local B=(d.y-D.y)/(d.x-D.x)local y=d.y-B*d.x return B*P+y end function d.DeltaTimeToTimescale(D,d)return d/.016666666666667 end function d.SecondsToTick(D,d)return.016666666666667/d end function d.ExptValueInSeconds(q,d,D,P)return 1-math.pow(d/D,1/(60.0*P))end function d.NormalizedDefaultExptValueInSeconds(P,d)return P:ExptValueInSeconds(D,1,d)end return d
--!nonstrict
local CurveUtil = {	}
local DEFAULT_THRESHOLD = 0.01

function CurveUtil:Expt(start, to, pct, dt_scale)
	if math.abs(to - start) < DEFAULT_THRESHOLD then
		return to
	end

	local y = CurveUtil:Expty(start,to,pct,dt_scale)

	--rtv = start + (to - start) * timescaled_friction--
	local delta = (to - start) * y
	return start + delta
end

function CurveUtil:Expty(start, to, pct, dt_scale)
	--y = e ^ (-a * timescale)--
	local friction = 1 - pct
	local a = -math.log(friction)
	return 1 - math.exp(-a * dt_scale)
end

function CurveUtil:Sign(val)
	if val > 0 then
		return 1
	elseif val < 0 then
		return -1
	else
		return 0
	end
end

function CurveUtil:BezierValForT(p0, p1, p2, p3, t)
	local cp0 = (1 - t) * (1 - t) * (1 - t)
	local cp1 = 3 * t * (1-t)*(1-t)
	local cp2 = 3 * t * t * (1 - t)
	local cp3 = t * t * t
	return cp0 * p0 + cp1 * p1 + cp2 * p2 + cp3 * p3
end

CurveUtil._BezierPt2ForT = { x = 0; y = 0 }
function CurveUtil:BezierPt2ForT(
	p0x, p0y,
	p1x, p1y,
	p2x, p2y,
	p3x, p3y,
	t)

	CurveUtil._BezierPt2ForT.x = CurveUtil:BezierValForT(p0x,p1x,p2x,p3x,t)
	CurveUtil._BezierPt2ForT.y = CurveUtil:BezierValForT(p0y,p1y,p2y,p3y,t)
	return CurveUtil._BezierPt2ForT
end

function CurveUtil:YForPointOf2PtLine(pt1, pt2, x)
	--(y - y1)/(x - x1) = m--
	local m = (pt1.y - pt2.y) / (pt1.x - pt2.x)
	--y - mx = b--
	local b = pt1.y - m * pt1.x
	return m * x + b
end

function CurveUtil:DeltaTimeToTimescale(s_frame_delta_time)
	return s_frame_delta_time / (1.0 / 60.0)
end

function CurveUtil:SecondsToTick(sec)
	return (1 / 60.0) / sec
end

function CurveUtil:ExptValueInSeconds(threshold, start, seconds)
		return 1 - math.pow((threshold / start), 1 / (60.0 * seconds))
end

function CurveUtil:NormalizedDefaultExptValueInSeconds(seconds)
		return self:ExptValueInSeconds(DEFAULT_THRESHOLD, 1, seconds)
end

return CurveUtil
