Home > Backend Development > C++ > How Can I Generate More Natural-Looking Island Terrain Maps Instead of Circular Edges Using a Gradient Circle Map Generator?

How Can I Generate More Natural-Looking Island Terrain Maps Instead of Circular Edges Using a Gradient Circle Map Generator?

Susan Sarandon
Release: 2025-01-07 12:16:39
Original
767 people have browsed it

How Can I Generate More Natural-Looking Island Terrain Maps Instead of Circular Edges Using a Gradient Circle Map Generator?

Addressing the Issue with Circular Edges in Gradient Circle Map Generator

In your map generator, you're using a method of creating islands using gradients, which leads to circular edges. This issue arises because the Perlin noise is multiplied by a color gradient, resulting in an uneven distribution.

Alternative Approach: Diamond and Square Algorithm

As suggested by another commenter, consider using the Diamond and Square algorithm instead, which generates more natural-looking terrain. Here's an overview of the steps involved:

Configure Generation Properties

Define parameters such as minimum and maximum elevation, sea level, and elevation ranges for vegetation, sand, dirt, etc.

Create Terrain Height Map

Employ a modified Diamond and Square algorithm to generate a terrain map with height values. Adjust the algorithm to create island-like terrains by initializing corners with the lowest elevation, ignoring the first diamond step, and correcting border points to the minimal elevation after each square iteration.

Create Surface Map

Map elevation values to surface features such as water, snow, dirt, sand, and vegetation based on elevation ranges.

Additional Features

Add additional features based on slope, such as rocks and cliffs.

Implementation in C

Here's a C code snippet that demonstrates the Diamond and Square algorithm for generating terrain height maps:

void map_random(int _xs,int _ys)
{
    float a,b; int c,t,f;
    int x,y,z,xx,yy,mxs,mys,dx,dy,dx2,dy2,r,r2;
    int **ter=NULL,**typ=NULL;
    Randomize();
    // align resolution to power of 2
    for (mxs=1;mxs+1<_xs;mxs<<=1); if (mxs<3) mxs=3;
    for (mys=1;mys+1<_ys;mys<<=1); if (mys<3) mys=3;
    ter=new int*[mys+1]; for (y=0;y<=mys;y++) ter[y]=new int[mxs+1];
    typ=new int*[mys+1]; for (y=0;y<=mys;y++) typ[y]=new int[mxs+1];

    // [Terrain]
    // diamond & square random height map -> ter[][]
    dx=mxs; dx2=dx>>1; r=1<<16;                     // init step,half step and randomness
    dy=mys; dy2=dy>>1; r2=r>>1;
    // set corners values
    ter[  0][  0]=-r2;
    ter[  0][mxs]= -r2;
    ter[mys][  0]= -r2;
    ter[mys][mxs]= -r2;
    ter[dy2][dx2]= r2;
    for (;dx2|dy2;dx=dx2,dx2>>=1,dy=dy2,dy2>>=1)    // subdivide step until full image is filled
    {
        if (!dx) dx=1;
        if (!dy) dy=1;
        // diamond (skip first one for islands)
        for (y=dy2,yy=mys-dy2;y<=yy;y+=dy)
            for (x=dx2,xx=mxs-dx2;x<=xx;x+=dx)
                ter[y][x]=((ter[y-dy2][x-dx2]+ter[y-dy2][x+dx2]+ter[y+dy2][x-dx2]+ter[y+dy2][x+dx2])>>2)+Random(r)-r2;
        // square
        for (y=dy2,yy=mys-dy2;y<=yy;y+=dy)
            for (x=dx ,xx=mxs-dx ;x<=xx;x+=dx)
                ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y-dy2][x]+ter[y+dy2][x])>>2)+Random(r)-r2;
        for (y=dy ,yy=mys-dy ;y<=yy;y+=dy)
            for (x=dx2,xx=mxs-dx2;x<=xx;x+=dx)
                ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y-dy2][x]+ter[y+dy2][x])>>2)+Random(r)-r2;
        for (x=dx2,xx=mxs-dx2;x<=xx;x+=dx)
        {
            y=  0; ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y+dy2][x])/3)+Random(r)-r2;
            y=mys; ter[y][x]=((ter[y][x-dx2]+ter[y][x+dx2]+ter[y-dy2][x])/3)+Random(r)-r2;
        }
        for (y=dy2,yy=mys-dy2;y<=yy;y+=dy)
        {
            x=  0; ter[y][x]=((ter[y][x+dx2]+ter[y-dy2][x]+ter[y+dy2][x])/3)+Random(r)-r2;
            x=mxs; ter[y][x]=((ter[y][x-dx2]+ter[y-dy2][x]+ter[y+dy2][x])/3)+Random(r)-r2;
        }
    }
    // rescale to <h0,h1>
    xx=ter[0][0]; yy=xx;
    for (y=0;y<mys;y++)
        for (x=0;x<mxs;x++)
        {
            z=ter[y][x];
            if (xx>z) xx=z;
            if (yy<z) yy=z;
        }
    for (y=0;y<mys;y++)
        for (x=0;x<mxs;x++)
            ter[y][x]=h0+(((ter[y][x]-xx)*(h1-h0))/(yy-xx));
}
Copy after login

This algorithm produces natural-looking terrain maps that can be used as a foundation for your island generator.

The above is the detailed content of How Can I Generate More Natural-Looking Island Terrain Maps Instead of Circular Edges Using a Gradient Circle Map Generator?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template