如何将正方形上的坐标转换为圆上的坐标?
我正在开发一款独立视频游戏,并且一直在这样的假设下进行操作:因为我的控制器上的拇指杆具有圆形运动范围,所以它返回“圆形”坐标;也就是说,笛卡尔坐标被限制在一个圆形区域(半径为 1)。事实上,坐标是“正方形”;例如,右上角的拇指杆位置记录为 x=1,y=1。当我将坐标从笛卡尔坐标转换为极坐标时,幅度可能会超过 1 - 这会导致玩家沿对角线移动的速度比垂直或水平移动的速度更快。
因此,为了澄清,我想以方向和幅度来记录模拟操纵杆的位置,其中幅度在 0 和 1 之间。操纵杆返回方形平面上的坐标,因此只需将坐标从笛卡尔坐标转换为极坐标还不够。我想我需要转换坐标空间,但这已经突破了我猴脑的极限。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
请参阅将正方形映射到圆形。映射还有一个很好的可视化效果。你得到:
See Mapping a Square to a Circle. There's also a nice visualization for the mapping. You get:
该映射不是唯一的。这个问题还有很多其他的解决方案。
例如,此映射也将起作用
其中 (u,v) 为圆盘坐标和(x,y)是方坐标。
一张图片胜过一千个单词,因此这里有一些图像来说明映射及其逆的非唯一性。
有关此其他映射的 C++ 实现
,请访问http://squirulous.blogspot.com/2015/09/fg-squircle -mapping.html
有关映射结果的更多图像,请参阅 http://squirulous.blogspot.com。
另请参阅“平方圆盘的分析方法”,了解讨论不同映射方程及其证明和推导的论文。
The mapping is not unique. There are many other solutions to this question.
For example, this mapping will also work
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 tohttp://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.
将每个值除以幅度,将所有值标准化为单位向量,例如,
但是,这可能会产生裁剪幅度的效果,而不是对内部值进行标准化。也就是说,您将获得推送的控制器的相同值“完全”进入左上角,控制器几乎完全推入同一方向。
Divide each value by the magnitude to normalize all values to a unit vector, e.g.
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.
我迟到了很多年,但我想在回过头来更深入地研究这个问题之后,我想分享一下我能够解决这个问题的方法。认为有更好的解决方案,但找不到。
我最近不得不在 JavaScript 中做类似的事情,并创建了一种将单位正方形的
X
和Y
规范化(或映射?)到四分之一单位圆的方法,得出速度为V
,方向为d
。这用于生成具有随机值的流场网格点。我使用
(n * 2) - 1
来获取X
和Y
值,其中n
是随机值0
和1
之间的数字。 X 和 Y 的值在-1
和1
之间。首先,我们得到
X,Y
的斜边或h
。然后我们得到
X
和h
之间的角度,为Δ
绝对值|•|
。我们得到绝对值,所以我们不会得到负的V
现在我们有了角度,我们可以沿着该角度延伸斜边。我们通过将
X
最大化为 1 来实现这一点。我们称之为h'
因为我们使用了绝对值,所以这会改变沿原点的方向。我们这样解释。
这样,现在我们可以标准化
h
与h'
。要获得真正的
Δ
或d
,我们必须在某些情况下纠正它的方向逻辑。我们将使用度数转换为弧度,然后使用之前计算的
Δ
。逻辑如下:
为了澄清,每种情况都对应于网格/圆的一个象限。
X ≥ 0
且Y ≥ 0
,则toRad(90) mod Δ
X ≥ 0
且 <代码>Y < 0,则Δ + toRad(270)
X
0
且Y ≤ 0
,则Δ + toRad(180)
X
0
和Y > 0
,然后Δ + toRad(90)
这将为您提供以弧度为单位的方向旋转。请注意,将 360° 重置回 0 可能会很有用。
这基本上就是我的想法。在某种程度上,它对值进行插值,使其保持在 0 和 1 之间,因此
1,0
和1,1
等值都等于 1。其中1 ,0
是 100% 靠右,1,1
是 100% 靠上/右前。X
和Y
的负值只会沿着各自的轴翻转方向。如果X,Y
等于0,那么V
和d
也为0。我希望这可以帮助人们避免将来的头痛。
I'm many years late but I thought I'd share what I was able to figure out for this problem after going back and looking into it deeper. Thought there was a better solution but couldn't find one.
I recently had to do something similar in JavaScript and created a way to normalize(or map?) the
X
andY
of a unit square to a quarter unit circle, deriving the velocity asV
, and Direction asd
. This was used to generate flow field grid points with random values.I used
(n * 2) - 1
to get theX
andY
values, wheren
is a random number between0
and1
. The values of X and Y are between-1
and1
.First, we get the hypotenuse, or
h
, ofX,Y
.Then we get the angle, as
∆
, betweenX
andh
as an absolute value|•|
. We get the absolute value so we don't get a negativeV
Now that we have angle, we can extend the hypotenuse along that angle. We do so by maxing out
X
to 1. Well call thish'
Because we used the absolute value, this changes the orientation along the origin point. We account for that like so.
With that, now we can normalize
h
withh'
.To get the true
∆
, ord
, we're going to have to correct for it's orientation with some case logic.We'll be using degrees converted to radians, then using the
∆
calculated before.The logic is as follows:
To clarify, each case coresponds to a quadrant of the grid/circle.
X ≥ 0
andY ≥ 0
, thentoRad(90) mod ∆
X ≥ 0
andY < 0
, then∆ + toRad(270)
X < 0
andY ≤ 0
, then∆ + toRad(180)
X < 0
andY > 0
, then∆ + toRad(90)
This will give you the rotation of direction in radians. Note that it may be useful to reset 360° back to 0.
That's basically what I came up with. In a way it interpolates the values so that it stays between 0 and 1, so values like
1,0
and1,1
both equal to 1. Where1,0
is 100% to right and1,1
is 100% to the top/forward right. Negative values forX
andY
just flip orientation along there respective axis. IfX,Y
are equal to 0, thenV
andd
are also 0.I hope this helps someone avoid a headache in the future.