如何将正方形上的坐标转换为圆上的坐标?

发布于 2024-08-09 01:38:25 字数 319 浏览 5 评论 0原文

我正在开发一款独立视频游戏,并且一直在这样的假设下进行操作:因为我的控制器上的拇指杆具有圆形运动范围,所以它返回“圆形”坐标;也就是说,笛卡尔坐标被限制在一个圆形区域(半径为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无可置疑 2024-08-16 01:38:25

请参阅将正方形映射到圆形。映射还有一个很好的可视化效果。你得到:

xCircle = xSquare * sqrt(1 - 0.5*ySquare^2)
yCircle = ySquare * sqrt(1 - 0.5*xSquare^2)

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)
浪漫人生路 2024-08-16 01:38:25

该映射不是唯一的。这个问题还有很多其他的解决方案。

例如,此映射也将起作用

u = x √(x2 + y2 - x2y2) / √(x2 + y2)

v = y √(x2 + y2 - x2y2) / √(x2 + y2)

其中 (u,v) 为圆盘坐标和(x,y)是方坐标。

一张图片胜过一千个单词,因此这里有一些图像来说明映射及其逆的非唯一性。

圆形布雷迪束


squared Boston Celtics

有关此其他映射的 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

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.

circular Brady bunch


squared Boston Celtics

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.

童话 2024-08-16 01:38:25

将每个值除以幅度,将所有值标准化为单位向量,例如,

magn = sqrt(x * x + y * y);
newx = magn > 1.0 ? x / magn : x;
newy = magn > 1.0 ? y / magn : y;

但是,这可能会产生裁剪幅度的效果,而不是对内部值进行标准化。也就是说,您将获得推送的控制器的相同值“完全”进入左上角,控制器几乎完全推入同一方向。

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.

萌逼全场 2024-08-16 01:38:25

我迟到了很多年,但我想在回过头来更深入地研究这个问题之后,我想分享一下我能够解决这个问题的方法。认为有更好的解决方案,但找不到。

我最近不得不在 JavaScript 中做类似的事情,并创建了一种将单位正方形的 XY 规范化(或映射?)到四分之一单位圆的方法,得出速度为V,方向为d。这用于生成具有随机值的流场网格点。

我使用 (n * 2) - 1 来获取 XY 值,其中 n 是随机值01 之间的数字。 X 和 Y 的值在 -11 之间。

首先,我们得到 X,Y 的斜边或 h

h = √(X² + Y²)

然后我们得到 Xh 之间的角度,为 Δ绝对值|•|。我们得到绝对值,所以我们不会得到负的 V

Δ = |arcsin(X/h)|

现在我们有了角度,我们可以沿着该角度延伸斜边。我们通过将 X 最大化为 1 来实现这一点。我们称之为 h'

h' = 1/cos(Δ)

因为我们使用了绝对值,所以这会改变沿原点的方向。我们这样解释。

q = 45(π/180)

如果 (Δ ≥ q) h' = 1/cos(q - (Δ mod q))

这样,现在我们可以标准化hh'

V = h/h'

要获得真正的 Δd,我们必须在某些情况下纠正它的方向逻辑。

我们将使用度数转换为弧度,然后使用之前计算的 Δ

逻辑如下:

 (X ≥ 0)?(Y ≥ 0)?toRad(90) mod ∆: ∆ + toRad(270):(Y ≤ 0)? ∆ + toRad(180): ∆ + toRad(90)

为了澄清,每种情况都对应于网格/圆的一个象限。

  • 如果 X ≥ 0Y ≥ 0,则 toRad(90) mod Δ
  • 如果 X ≥ 0 且 <代码>Y < 0,则 Δ + toRad(270)
  • 如果 X 0Y ≤ 0,则 Δ + toRad(180)
  • 如果 X 0Y > 0,然后Δ + toRad(90)

这将为您提供以弧度为单位的方向旋转。请注意,将 360° 重置回 0 可能会很有用。

这基本上就是我的想法。在某种程度上,它对值进行插值,使其保持在 0 和 1 之间,因此 1,01,1 等值都等于 1。其中 1 ,0 是 100% 靠右,1,1 是 100% 靠上/右前。 XY 的负值只会沿着各自的轴翻转方向。如果X,Y等于0,那么Vd也为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 and Y of a unit square to a quarter unit circle, deriving the velocity as V, and Direction as d. This was used to generate flow field grid points with random values.

I used (n * 2) - 1 to get the X and Y values, where n is a random number between 0 and 1. The values of X and Y are between -1 and 1.

First, we get the hypotenuse, or h, of X,Y.

h = √(X² + Y²)

Then we get the angle, as , between X and h as an absolute value |•|. We get the absolute value so we don't get a negative V

∆ = |arcsin(X/h)|

Now that we have angle, we can extend the hypotenuse along that angle. We do so by maxing out X to 1. Well call this h'

h' = 1/cos(∆)

Because we used the absolute value, this changes the orientation along the origin point. We account for that like so.

q = 45(π/180)

if (∆ ≥ q) h' = 1/cos(q - (∆ mod q))

With that, now we can normalize h with h'.

V = h/h'

To get the true , or d, 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:

 (X ≥ 0)?(Y ≥ 0)?toRad(90) mod ∆: ∆ + toRad(270):(Y ≤ 0)? ∆ + toRad(180): ∆ + toRad(90)

To clarify, each case coresponds to a quadrant of the grid/circle.

  • If X ≥ 0 and Y ≥ 0, then toRad(90) mod ∆
  • If X ≥ 0 and Y < 0, then ∆ + toRad(270)
  • If X < 0 and Y ≤ 0, then ∆ + toRad(180)
  • If X < 0 and Y > 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 and 1,1 both equal to 1. Where 1,0 is 100% to right and 1,1 is 100% to the top/forward right. Negative values for X and Y just flip orientation along there respective axis. If X,Y are equal to 0, then V and d are also 0.

I hope this helps someone avoid a headache in the future.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文