Search code examples
c#mathcoordinatesxinput

converting xinput coordinates to a square


i'm working on a small c# program that uses xinput to read the xbox 360 thumb stick.

i have no problem with reading the coordinates and normalizing the values so i get a float between -1 and +1 for X and Y directions. the problem i have is that the stick itself is physically limited to a circle and in my case i would like to "stretch out" the coordinates so it becomes more of a square than a circle.

the reason is that each direction is controlling a motor and if i move the stick for example top right i would like both X and Y to become 1. since the stick is circular this is not possible and this also makes it impossible to make both motors run at full speed.

any advice?


Solution

  • So you want a point on a circle of radius r to be mapped to a point on a square of radius r on the same ray through the origin. Toward that goal you have to compute the radius using the usual formula

    r = sqrt(x*x+y*y)
    

    and then from that the scale factor

    f = r / max ( abs(x), abs(y) )
    

    and in the end replace x by f*x and y by f*y.

    One can vary this computation by noting that the factor is

    f = sqrt ( 1 + (x*x)/(y*y) )
    

    if abs(y) > abs(x) and

    f = sqrt ( 1 + (y*y)/(x*x) )
    

    in the opposite case. Or by noting that the largest coordinate gets replaced by r and the smaller scaled accordingly, which also does not reduce the logistics by much.