**Answer**

It’s all a bit easier to discuss if we start with horizontal lines, like so:

As Ilmari Karonen said, this is just a *displacement map*. You start with a 3D topography *h*(*x*,*y*), and then each point (*x*,*y*) in the result should use the line starting at *y*_{0} = *y* − *h*(*x*,*y*).

With raster graphics, this can be rendered straight away, but to get clean vector lines we’d actually need to work the other way around: each line should be parameterised as

*f*_{y0}(*x*) = *y*_{0} + *h*(*x*, *f*_{y0}(*x*))

The problem is that this is only an *implicit* defining equation, because the RHS contains *y* = *f*_{y0}(*x*). This could be solved with Newton-Raphson, but there’s a simpler way: just construct the lines going from left to right, and at each point go up or down as needed to fulfill the equation. Assuming continuity, this is always just a small update, so we can approximate *h* as constant there.

Implementation in Haskell:

```
type ℝ = Double
horizContourLine ::
((ℝ,ℝ) -> ℝ) -- ^ The topography/height function
-> (ℝ,ℝ) -- ^ x-interval on which to render the path
-> ℝ -- ^ Step size / resolution along the path
-> ℝ -- ^ Base-level y-coordinate of the line
-> [(ℝ,ℝ)] -- ^ Trail line
horizContourLine h (x₀,xe) δx y₀ = go (x₀,y₀)
where go (x,y) = (x,yTgt)
: if x<xe then go (x+δx, yTgt)
else []
where yTgt = y₀ + h (x,y)
```

Then, with a suitable image input like

we get contours like

Full code: https://gist.github.com/leftaroundabout/8b7075d25adecdf16806ea5d7a7ea2aa

Rotation to diagonal lines is left as an exercise.

**Attribution***Source : Link , Question Author : aamee traders , Answer Author : leftaroundabout*