@@ -4192,6 +4192,18 @@ vector_elementwise(pgVector *vec, PyObject *_null)
41924192    return  (PyObject  * )proxy ;
41934193}
41944194
4195+ inline  double 
4196+ lerp (double  a , double  b , double  v )
4197+ {
4198+     return  a  +  (b  -  a ) *  v ;
4199+ }
4200+ 
4201+ inline  double 
4202+ invlerp (double  a , double  b , double  v )
4203+ {
4204+     return  (v  -  a ) / (b  -  a );
4205+ }
4206+ 
41954207static  PyObject  * 
41964208math_clamp (PyObject  * self , PyObject  * const  * args , Py_ssize_t  nargs )
41974209{
@@ -4233,6 +4245,72 @@ math_clamp(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
42334245    return  value ;
42344246}
42354247
4248+ #define  RAISE_ARG_TYPE_ERROR (var )                                     \
4249+     if (PyErr_Occurred()) {                                           \
4250+         return RAISE(PyExc_TypeError,                                 \
4251+                      "The argument '" var "' must be a real number"); \
4252+     }
4253+ 
4254+ static  PyObject  * 
4255+ math_invlerp (PyObject  * self , PyObject  * const  * args , Py_ssize_t  nargs )
4256+ {
4257+     if  (nargs  !=  3 )
4258+         return  RAISE (PyExc_TypeError ,
4259+                      "invlerp requires exactly 3 numeric arguments" );
4260+ 
4261+     double  a  =  PyFloat_AsDouble (args [0 ]);
4262+     RAISE_ARG_TYPE_ERROR ("a" )
4263+     double  b  =  PyFloat_AsDouble (args [1 ]);
4264+     RAISE_ARG_TYPE_ERROR ("b" )
4265+     double  t  =  PyFloat_AsDouble (args [2 ]);
4266+     RAISE_ARG_TYPE_ERROR ("value" )
4267+ 
4268+     if  (PyErr_Occurred ())
4269+         return  RAISE (PyExc_ValueError ,
4270+                      "invalid argument values passed to invlerp, numbers " 
4271+                      "might be too small or too big" );
4272+ 
4273+     if  (b  -  a  ==  0 )
4274+         return  RAISE (PyExc_ValueError ,
4275+                      "the result of b - a needs to be different from zero" );
4276+ 
4277+     return  PyFloat_FromDouble (invlerp (a , b , t ));
4278+ }
4279+ 
4280+ #
4281+ 
4282+ static  PyObject  * 
4283+ math_remap (PyObject  * self , PyObject  * const  * args , Py_ssize_t  nargs )
4284+ {
4285+     if  (nargs  !=  5 )
4286+         return  RAISE (PyExc_TypeError ,
4287+                      "remap requires exactly 5 numeric arguments" );
4288+ 
4289+     PyObject  * i_min  =  args [0 ];
4290+     PyObject  * i_max  =  args [1 ];
4291+     PyObject  * o_min  =  args [2 ];
4292+     PyObject  * o_max  =  args [3 ];
4293+     PyObject  * value  =  args [4 ];
4294+ 
4295+     double  v  =  PyFloat_AsDouble (value );
4296+     RAISE_ARG_TYPE_ERROR ("value" )
4297+     double  a  =  PyFloat_AsDouble (i_min );
4298+     RAISE_ARG_TYPE_ERROR ("i_min" )
4299+     double  b  =  PyFloat_AsDouble (i_max );
4300+     RAISE_ARG_TYPE_ERROR ("i_max" )
4301+     double  c  =  PyFloat_AsDouble (o_min );
4302+     RAISE_ARG_TYPE_ERROR ("o_min" )
4303+     double  d  =  PyFloat_AsDouble (o_max );
4304+     RAISE_ARG_TYPE_ERROR ("o_max" )
4305+ 
4306+     if  (b  -  a  ==  0 )
4307+         return  RAISE (
4308+             PyExc_ValueError ,
4309+             "the result of i_max - i_min needs to be different from zero" );
4310+ 
4311+     return  PyFloat_FromDouble (lerp (c , d , invlerp (a , b , v )));
4312+ }
4313+ 
42364314static  PyObject  * 
42374315math_lerp (PyObject  * self , PyObject  * const  * args , Py_ssize_t  nargs )
42384316{
@@ -4343,6 +4421,8 @@ math_disable_swizzling(pgVector *self, PyObject *_null)
43434421static  PyMethodDef  _math_methods [] =  {
43444422    {"clamp" , (PyCFunction )math_clamp , METH_FASTCALL , DOC_MATH_CLAMP },
43454423    {"lerp" , (PyCFunction )math_lerp , METH_FASTCALL , DOC_MATH_LERP },
4424+     {"invlerp" , (PyCFunction )math_invlerp , METH_FASTCALL , DOC_MATH_INVLERP },
4425+     {"remap" , (PyCFunction )math_remap , METH_FASTCALL , DOC_MATH_REMAP },
43464426    {"smoothstep" , (PyCFunction )math_smoothstep , METH_FASTCALL ,
43474427     DOC_MATH_SMOOTHSTEP },
43484428    {"enable_swizzling" , (PyCFunction )math_enable_swizzling , METH_NOARGS ,
0 commit comments