1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Timing.mli *)typet={x1:float;y1:float;x2:float;y2:float}letclamp01v=Float.max0.(Float.min1.v)letbezierx1y1x2y2={x1=clamp01x1;y1;x2=clamp01x2;y2}letlinear=bezier0.0.1.1.letease_in=bezier0.420.1.1.letease_out=bezier0.0.0.581.letease_in_out=bezier0.420.0.581.letdefault=bezier0.250.10.251.(* one coordinate of the curve at s, its ends 0 and 1: its polynomial's
* coefficients, Horner's way *)letcoord(p1:float)(p2:float)(s:float):float=letc=3.*.p1inletb=(3.*.(p2-.p1))-.cinleta=1.-.c-.bin((((a*.s)+.b)*.s)+.c)*.sletslope(p1:float)(p2:float)(s:float):float=letc=3.*.p1inletb=(3.*.(p2-.p1))-.cinleta=1.-.c-.bin(((3.*.a*.s)+.(2.*.b))*.s)+.c(* the s where x(s) = t *)letsolve(c:t)(t:float):float=letrecnewtonsk=ifk=0thenNoneelselete=coordc.x1c.x2s-.tinifFloat.abse<1e-7thenSomeselseletd=slopec.x1c.x2sinifFloat.absd<1e-6thenNoneelsenewton(s-.(e/.d))(k-1)inmatchnewtont8with|Someswhens>=0.&&s<=1.->s|_->letrecbisectlohik=lets=(lo+.hi)/.2.inifk=0thenselseifcoordc.x1c.x2s<tthenbisectshi(k-1)elsebisectlos(k-1)inbisect0.1.40letat(c:t)(t:float):float=lett=clamp01tinift=0.||t=1.thentelsecoordc.y1c.y2(solvect)