问题
I'm developing an indie video game, and have been operating under the assumption that because the thumbstick on my controller has a circular range of motion, it returns "circular" coordinates; that is, Cartesian coordinates constrained to a circular area (of radius 1). In fact, the coordinates are "square"; e.g., the top-right thumbstick position registers as x=1,y=1. When I convert the coordinates from Cartesian to polar, the magnitude can exceed 1 - which has the effect that the player can move faster diagonally than they can vertically or horizontally.
So, to clarify, I want to record the position of an analog thumbstick in terms of a direction and magnitude, where the magnitude is between 0 and 1. The thumbstick returns coordinates on a square plane, so simply converting the coordinates from Cartesian to polar is not sufficient. I think I need to convert the coordinate space, but that is pressing the limits of my monkey brain.
回答1:
See Mapping a Square to a Circle. There's also a nice visualization for the mapping. You get:
xCircle = xSquare * sqrt(1 - 0.5*ySquare^2)
yCircle = ySquare * sqrt(1 - 0.5*xSquare^2)
回答2:
The mapping is not unique. There are many other solutions to this question.
For example, this mapping will also work
u = x √(x² + y² - x²y²) / √(x² + y²)
v = y √(x² + y² - x²y²) / √(x² + y²)
where (u,v) are circular disc coordinates and (x,y) are square coordinates.
A picture is worth a thousand words, so here are some images to illustrate the non-uniqueness of the mapping and its inverse.
For a C++ implementation
of this other mapping, go to
http://squircular.blogspot.com/2015/09/fg-squircle-mapping.html
See http://squircular.blogspot.com for more images of mapping results.
See also "Analytical Methods for Squaring the Disc" for a paper discussing different mapping equations with proofs and derivations.
回答3:
Divide each value by the magnitude to normalize all values to a unit vector, e.g.
magn = sqrt(x * x + y * y);
newx = magn > 1.0 ? x / magn : x;
newy = magn > 1.0 ? y / magn : y;
However, this may have the effect of clipping the magnitude instead of normalizing for the interior values.. That is, you'll get the same value for a controller pushed "fully" into the upper-left and a controller almost pushed fully into the same direction.
来源:https://stackoverflow.com/questions/1621831/how-can-i-convert-coordinates-on-a-square-to-coordinates-on-a-circle