This is a simplified kind of inverse kinematics. The function finds an arm position that will reach a certain point. Simplified in the sense that this is done just using vector maths instead of an actual IK algorithm. You can look at this desmos graph if you want to see the maths more closely.
Input:
- Shoulder position (sx,sy)
- Hand position (ex,ey)
- Arm length (dist)
Output:
- Elbow position (kx,ky)
- Hand position (ex,ey)
The arm can only reach so far, hence the returned hand position. You can see the difference if you try to over-extend the arm.
It hasn't been optimised for tokens and the variable names don't really make sense, so apologies about that
function inv_kin(_sx,_sy,_ex,_ey,_dist) local mx,my=(_ex-_sx)/2,(_ey-_sy)/2 local mm=sqrt(mx^2+my^2) if mm>_dist then return {kx=_sx+_dist*mx/mm,ky=_sy+_dist*my/mm,ex=_sx+2*_dist*mx/mm,ey=_sy+2*_dist*my/mm} end local km=sqrt(_dist^2-mm^2) local kx,ky=km*-my/mm,km*mx/mm return {kx=_sx+mx+kx,ky=_sy+my+ky,ex=_ex,ey=_ey} end |
And in the draw function
local ik=inv_kin(body_x,body_y,hand_x,hand_y,40) ... spr(3,body_x-4,body_y-4) spr(2,ik.ex-4,ik.ey-4) spr(1,ik.kx-4,ik.ky -4) |
If you want to change the elbow direction, change the line
local kx,ky=km*-my/mm,km*mx/mm
to
local kx,ky=km*my/mm,km*-mx/mm
(swap the sign of mx and my)
[Please log in to post a comment]