Skip to content

Instantly share code, notes, and snippets.

@piyo7
Created November 21, 2017 03:23
Show Gist options
  • Save piyo7/5264b8513c4db8c802005932eb209c46 to your computer and use it in GitHub Desktop.
Save piyo7/5264b8513c4db8c802005932eb209c46 to your computer and use it in GitHub Desktop.
N次元のいかつい極座標変換もメソッドチェーンでしゅっと実装できるお ref: https://qiita.com/piyo7/items/73023be87fef02b32132
\begin{align}
x &= r \cos(\phi) \\
y &= r \sin(\phi) \\
\end{align}
\begin{align}
x &= r \cos(\phi_1) \\
y &= r \sin(\phi_1) \cos(\phi_2) \\
z &= r \sin(\phi_1) \sin(\phi_2) \\
\end{align}
\begin{align}
x_1 &= r \cos(\phi_1) \\
x_2 &= r \sin(\phi_1) \cos(\phi_2) \\
x_3 &= r \sin(\phi_1) \sin(\phi_2) \cos(\phi_3) \\
&\vdots \\
x_{n-1} &= r \sin(\phi_1) \dots \sin(\phi_{n-2}) \cos(\phi_{n-1}) \\
x_n &= r \sin(\phi_1) \dots \sin(\phi_{n-2}) \sin(\phi_{n-1}) \\
\end{align}
phis.map(math.sin).scan(1.0)(_ * _)
phis.map(math.cos) :+ 1.0
def toEuclidean(r: Double, phis: Seq[Double]): Seq[Double] = {
phis.map(math.sin).scan(1.0)(_ * _).
zip(phis.map(math.cos) :+ 1.0).
map { case (a, b) => r * a * b }
}
\begin{align}
r &= \sqrt{x_n^2 + x_{n-1}^2 + \dots + x_1^2} \\
\phi_1 &= \arccos \frac{x_1}{\sqrt{x_n^2 + x_{n-1}^2 + \dots + x_1^2}} \\
\phi_2 &= \arccos \frac{x_2}{\sqrt{x_n^2 + x_{n-1}^2 + \dots + x_2^2}} \\
&\vdots \\
\phi_{n-2} &= \arccos \frac{x_{n-2}}{\sqrt{x_n^2 + x_{n-1}^2 + x_{n-2}^2}} \\
\phi_{n-1} &=
\begin{cases}
\arccos \frac{x_{n-1}}{\sqrt{x_n^2 + x_{n-1}^2}} &x_n \geq 0\\
- \arccos \frac{x_{n-1}}{\sqrt{x_n^2 + x_{n-1}^2}} &x_n < 0 \\
\end{cases}
\end{align}
def toSpherical(xs: Seq[Double]): (Double, Seq[Double]) = {
val rs = xs.scanRight(0.0) { case (x, sum) => x * x + sum }.map(math.sqrt)
val phis = xs.init.zip(rs).zipWithIndex.
map {
case ((_, 0.0), _) =>
0.0
case ((a, b), i) if i == xs.size - 2 && xs.last < 0.0 =>
-math.acos(a / b)
case ((a, b), _) =>
math.acos(a / b)
}
(rs.head, phis)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment