generative-art-0.1.0.0
Safe HaskellSafe-Inferred
LanguageHaskell2010

Geometry.Processes.Geodesics

Synopsis

Documentation

geodesicEquation Source #

Arguments

:: (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