Algorithm to generate a hill

1.9k Views Asked by At

Setup
I recently started to work with Unity. I want to generate a custom terrain at runtime. To do this i take a grid with a variable amount of squares. For each of the squares i calculate the height with a exchangeable height function. The height function takes the X and Z coordinate as arguments. X and Z range between 0 and 1.
I wrote some height function using perlin noise and random numbers.

Problem
I want to generate a hill. The hilltop (height 1.0) should be in the center (coordinate 0.5, 0.5). And the edges mark the bottom of the hill (height 0.0).

My best bet was a gaussian like function. The result is quite what i am looking for. A smooth top and leveled at the edges. The problem is that the edges are always a bit raised. You can reduce that by scaling X and Z but this results in a smaller hill.

I also tried other functions. But they all have shortcomings like sharp edges or raised edges.

Can anyone help me pick an appropriate function? Or maybe a combination of functions?

4

There are 4 best solutions below

1
On BEST ANSWER

Here is a simple possibility:

Let $p(t) = (1-t)^2(1+t)^2$ and $f(x,y) = p(\min(1,\sqrt{x^2+y^2}))$.

This gives a hill of height $1$ at the origin and zero outside $[-1,1]^2$.

Looks like: enter image description here

To get a hill that peaks at $({1\over 2},{1 \over 2})$ and is zero outside $[0,1]^2$, use $g(x,y) = f(2x-{1 \over 2}, 2y-{1 \over 2})$.

0
On

Gaussian sounds good for a hill. I suggest you try dropping it everywhere by a little, but not allowing it to go below zero.

So first calculate the heights the way you already have.

Let $drop$ be the height at $(0,0.5)$

For every point where you have calculated the height, let $height_{new} = max(height_{old} - drop,0)$

0
On

You are going to have problems with a Gaussian because it vanishes only at infinity. You can however construct a "modified Gaussian", that vanishes (with all its derivatives) at the endpoints of an interval $[a, b]$ and equals $1$ at the midpoint: \begin{equation} G_{a, b}(x)=\exp\left( \frac{4}{b-a} + \frac{-1}{x-a} + \frac{-1}{b-x}\right). \end{equation} To construct a hill in the rectangle $[a_x, b_x]\times [a_y, b_y]$ you just need to multiply together two modified Gaussians:

\begin{equation} G_{a_x, b_x}(x)\cdot G_{a_y, b_y}(y). \end{equation}

Here's the result for the square $[0,1]\times[0,1]$: enter image description here

0
On

You can use a product of the classical "bump" function which is extremely smooth ( has infinitely many smooth derivatives everywhere ).

http://en.wikipedia.org/wiki/Bump_function In one dimension defined as:

$$b(x) = \begin{cases}e^{-\frac{1}{1-x^2}} & |x|<1\\0 & |x|>1\end{cases}$$

Then $b(x)^{c_x}b(y)^{c_y}$ would be a hill for any positive $c_x$ and $c_y$.