Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Documentation
:: (Double -> Vec2 -> Double) | Surface function \(f(t, \mathbf v)\) |
-> Double | Time \(t\) |
-> (Vec2, Vec2) | \((\mathbf v, \dot{\mathbf v})\) |
-> (Vec2, Vec2) | \((\dot{\mathbf v}, \ddot{\mathbf v})\) |
A geodesic is a path that takes no local detours: each move to a new point is done so that no other move would be faster. The shortest path between two points is always a geodesic.
This function allows creating the geodesic differential equation, suitable for
using in ODE solvers such as
rungeKuttaAdaptiveStep
.
Using this is very simple, the equation behind it is simple depending on your knowledge of differential geometry, and implementing it is a quite interesting exercise in algorithmic optimization.
\[ \begin{align} \ddot v^i &= \Gamma^i_{kl}\dot v^k\dot v^l \\ \Gamma^i_{kl} &= \frac12 g^{im} (g_{mk,l}+g_{ml,k}-g_{kl,m}) \\ g(f) &= \begin{pmatrix}1+\partial_{xx}f & \partial_xf\,\partial_yf \\ \partial_xf\,\partial_yf & 1+\partial_{yy}f\end{pmatrix} \end{align} \]
Example: hill and valley
We can use the following variation of the Cauchy distribution to build ourselves a hill with width parameter \(\gamma\),
\[ \text{Hill}_{\gamma}(\mathbf v_{\text{center}}, \mathbf v) = \left(1+\left\| \frac{\mathbf v-\mathbf v_{\text{center}}}{\gamma}\right\|^2\right)^{-1} \]
We can then pleace two of those, one at the top right with height 100 and one at the bottom left with height -33.
This is what a family of trajectories passing through our terrain looks like:
(w,h) = … -- Canvas size hill g v0 v = 1 / (1 + (normSquare
(v-.v0) / g^2)) geometry v = 100 * hill 55 (Vec2
(2/3*w) (1/3*h)) v - 33 * hill 55 (Vec2
(1/3*w) (2/3*h)) v startAngle =deg
45 solution =rungeKuttaAdaptiveStep
(geodesicEquation
geometry) (zero
,polar
startAngle 1) t0 dt0 tolNorm tol) where t0 = 0 dt0 = 1 tolNorm (x,v) =max
(norm
x) (norm
v) tol = 1e-3