先前问题中给出的函数是:
xCircle = xSquare * sqrt(1 - 0.5*ySquare^2) yCircle = ySquare * sqrt(1 - 0.5*xSquare^2)
来自将正方形映射到圆形 我的问题是:给定xCircle和yCircle...我怎样才能找到xSquare和ySquare?
我尝试了我所知道的所有代数,填了两页笔记,试图让沃尔夫拉姆阿尔法得到反函数,但这个问题超出了我的能力范围。
谢谢您的查看。
注:我使用x = xSquare,y = ySquare,u = xCircle和v = yCircle; 即(u,v)是圆盘坐标,(x,y)是方形坐标。
有关方程的C++实现,转到http://squircular.blogspot.com/2015/09/mapping-circle-to-square.html
请参见http://squircular.blogspot.com以获取更多示例图像。 另请参见http://arxiv.org/abs/1509.06344进行证明/推导。
此映射是以下映射的反向操作
=x√(1-½y²) =y√(1-½x²)附:映射并不唯一。还有其他映射。下面的图片说明了映射的非唯一性。
R = sqrt(xCircle^2 + yCircle^2)
的圆上。现在您需要将该圆扩展到一个半边长为 R 的正方形。if (xCircle < yCircle)
ySquare = R, xSquare = xCircle * R/yCircle
else
xSquare = R, ySquare = yCircle * R/xCircle
这是针对第一象限的,对于其他象限,您需要通过对符号进行一些微小的调整。
有很多方法可以做到这一点;这里是一种简单的方法。
想象一个以原点为中心,半径为R的圆和一个以原点为中心,边长为2R的正方形,我们希望将圆内和圆周上的所有点(坐标为(x,y))映射到正方形内和边界上的点。请注意,我们还可以使用极坐标(r, ø)(应该是phi)来描述圆内的点,其中
x = r cos ø,
y = r sin ø
(即r^2 = x^2 + y^2且r <= 1)。然后想象其他坐标x' = a(ø) x = a(ø) r cos ø和y' = a(ø) y(即,我们决定a不会依赖于r)。
为了将圆的边界(r = 1)映射到正方形的边界(x' = R),我们必须满足,在 ø < 45deg 的情况下,x' = a(ø) R cos ø = R,因此我们必须有 a(ø) = 1/cos ø。同样地,在 45 < ø < 90 的区域内,我们必须将圆的边界映射到 y' = R,从而在该区域内给出 a(ø) = 1/sin ø。继续沿着圆走,我们可以看到 a(ø) 必须始终为正数,因此从圆到正方形的最终映射为:x' = a(ø) x,
y' = a(ø) y
其中
ø = |arctan y/x| = arctan |y/x|
并且
当 ø ≤ 45 度(即当 x < y 时),a(ø) = 1/cos ø,而当 ø > 45 度时,a(ø) = 1/sin ø。我正在实现上面的解决方案,但结果并不令人满意。正方形坐标不是精确的。
这里是一个简单的反例:
应用上述表达式,我们得到新的正方形坐标
(x',y')=(u/v,r)=(0.625543242, 1),其中r=(u^2+v^2)^(1/2)。
这个点很接近,但不是预期的精确解。
我解决了一个根查找问题,以获得从正方形到圆的映射的反向表达式。你需要解决像上面那样的系统方程:
I) u = x*(1-y^2/2)^(1/2)
II) v = y*(1-x^2/2)^(1/2)
最终得到了8个根点作为解决方案。其中一个根点我已经实现到Excel-VBA中,下面我将在这里展示它,并且它运行得非常好。
' given the circle coordinates (u,v) caluclates the x coordinate on the square
Function circ2sqrX(u As Double, v As Double) As Double
Dim r As Double, signX As Double, u2 As Double, v2 As Double, uuvv As Double, temp1 As Double
u2 = u * u
v2 = v * v
r = Sqr(u2 + v2)
signX = 1
If v = 0 Or u = 0 Then
circ2sqrX = u
Exit Function
End If
If u < 0 Then
signX = -1
End If
If Abs(u) = Abs(v) And r = 1 Then
circ2sqrX = signX
Exit Function
End If
uuvv = (u2 - v2) * (u2 - v2) / 4
temp1 = 2 * Sqr(uuvv - u2 - v2 + 1)
circ2sqrX = -((temp1 - u2 + v2 - 2) * Sqr(temp1 + u2 - v2 + 2)) / (4 * u)
End Function
' given the circle coordinates (u,v) caluclates the y coordinate on the square
' make use of symetrie property
Function circ2sqrY(u As Double, v As Double) As Double
circ2sqrY=circ2sqrX(v,u)
End Function