how to continuously generate Perlin noise as an infinite map grows? - c#

EDIT: I ended up using the FastNoise library found here: https://github.com/Auburns/FastNoise It has everything under the sun which someone might need to generate many different kinds of noise. As the title might suggest its also quite fast!
I'm creating a 2D infinitely, procedural generated world. I load and unload chunks from disc as the player moves. I'm using a cellular automata function to define how local tiles within each chunk are designed but I need noise (Perlin in this case) to define what biome type each chunk will be as new ones are created. I understand how I would translate decimals between 0 and 1 to represent this, my only issue is that the tutorial I followed on creating Perlin noise requires that you pass it a predefined 2d array and returns a noise array of the same size. Because my world grows dynamically I'm a bit confused on how I would use a fixed sized array to designate new chunk types.
Other answers I've seen don't cover exactly how to handle the infinite part of noise generation. My best guess is that I need to somehow generate or expand the noise with each newly created chunk although how I do this stumps me.
Here is some code I translated to C# from here: http://devmag.org.za/2009/04/25/perlin-noise/
admittedly some of the math here I don't fully understand yet, especially the bitwise function!
public class PerlinNoiseGenerator
{
public int OctaveCount { get; set; }
public float Persistence { get; set; }
public PerlinNoiseGenerator(int octaveCount, float persistence)
{
this.OctaveCount = octaveCount;
this.Persistence = persistence;
}
public float[,] GenerateWhiteNoise(int width, int height)
{
float[,] noiseFieldToReturn = new float[width, height];
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
noiseFieldToReturn[i, j] = (float)Game1.Utility.RGenerator.NextDouble() % 1;
}
}
return noiseFieldToReturn;
}
public float[,] SmoothNoiseField(float[,] whiteNoise, int octave)
{
int width = whiteNoise.GetLength(0);
int height = whiteNoise.GetLength(1);
float[,] smoothField = new float[width, height];
int samplePeriod = 1 << octave;
float sampleFrequency = 1.0f / samplePeriod;
for(int i =0; i < width; i++)
{
int samplei0 = (i / samplePeriod) * samplePeriod;
int samplei1 = (samplei0 + samplePeriod) % width;
float horizontalBlend = (i - samplei0) * sampleFrequency;
for(int j =0; j < height; j++)
{
int samplej0 = (j/samplePeriod) * samplePeriod;
int samplej1 = (samplej0 + samplePeriod) % height;
float verticalBlend = (j - samplej0) * sampleFrequency;
float top = LinearInterpolate(whiteNoise[samplei0, samplej0],
whiteNoise[samplei1, samplej0], horizontalBlend);
float bottom = LinearInterpolate(whiteNoise[samplei0, samplej1],
whiteNoise[samplei1, samplej1], horizontalBlend);
smoothField[i, j] = LinearInterpolate(top, bottom, verticalBlend);
}
}
return smoothField;
}
public float[,] GeneratePerlinNoise(float[,] baseNoise, int octaveCount)
{
int width = baseNoise.GetLength(0);
int height = baseNoise.GetLength(1);
float[][,] smoothNoise = new float[octaveCount][,];
float persistance = .5f;
for(int i =0; i < octaveCount;i++)
{
smoothNoise[i] = SmoothNoiseField(baseNoise, i);
}
float[,] perlinNoise = new float[width, height];
float amplitude = 1f;
float totalAmplitude = 0.0f;
for(int octave = octaveCount - 1; octave > 0; octave-- )
{
amplitude *= persistance;
totalAmplitude += amplitude;
for(int i =0; i < width;i++)
{
for(int j =0; j < height; j++)
{
perlinNoise[i, j] += smoothNoise[octave][i, j] * amplitude;
}
}
}
for(int i =0; i < width; i++)
{
for(int j =0; j < height; j++)
{
perlinNoise[i, j] /= totalAmplitude;
}
}
return perlinNoise;
}
public float LinearInterpolate(float a, float b, float alpha)
{
return a * (1 - alpha) + alpha * b;
}
}
This code should compile and produces a FIXED size array of noise

The main thing you want to make sure is that the starting random noise is pseudo random, so you always have a "fixed random value" for a coordinate.
It might be that you'd have to rewrite your random noise generator, using the coordinates as input. I imagine your maps have a random seed number, so you could use this post as a starting point, adding 1 factor:
A pseudo-random number generator based on 2 inputs
For a bit of inspiration for your map making, I wrote this article a while back: https://steemit.com/map/#beeheap/create-a-fantasy-grid-map-in-excel
Added after your comment: the only function you'd need to change is the GenerateWhiteNoise one. I don't speak C#, but this is the general idea:
GenerateWhiteNoise(int x_start_coord, int y_start_coord, int random_seed) {
int default_x_width = 100;
int default_y_heigth = 50;
float[,] noiseFieldToReturn = new float[width, height];
for (in x = x_start_coord; i < default_x_width + x_start_coord; x++)
{
for (in y = y_start_coord; i < default_y_width + y_start_coord; y++)
{
noiseFieldToReturn[i, j] = (float)pseudo_rnd_value(x, y, random_seed);
}
}
return noiseFieldToReturn;
}
That should give you the pseudo random values you need to build your map tiles, the only thing you need is the coordinate of the player (x and y).

Related

Problem with world generation in unity c#

I want to create a world generation using two noise maps (altitude noise and moisture noise). I create maps of these noises and set them in the inspector to values between 0 and 1.
I want to get result like this:
If Elevation < 1000
{
If Moisture < 50: Desert
Else Forest
}
And it seems that I did it as it should, but for some reason the generation does not work correctly:
Here is my code:
for (int x=0; x < tilemap.Width; x++)
{
for (int y = 0; y < tilemap.Height; y++)
{
// Get height at this position
var height = noiseMap[y * tilemap.Width + x];
var moisureHeight = moisureMap[y * tilemap.Width + x];
// Loop over our configured tile types
for (int i = 0; i < TileTypes.Length; i++)
{
var TileType = TileTypes[i];
for (var j = 0; j < TileType.MoisureValues.Length; j++)
{
// If the height is smaller or equal then use this tiletype
if (height <= TileType.Height)
{
if (moisureHeight <=TileType.MoisureValues[j].MoisureHeight)
{
tilemap.SetTile(x, y, (int)TileType.MoisureValues[j].GroundTile);
break;
}
}
}
}
}
}

Interpolating 2d array of points

I have a 2d array of points (each point stored in my Points struct, which contains only 3 properties: X Y Z), with size of 128x128. I want to interpolate (stretch) this 2d array to greater size (132x132 for example). So far I have managed to interpolate X and Y coordinates of each point using linear interpolation (simply taking coordinates into array of double, interpolating it, and returning it to new 2d array of Points). Here is the code of linear interpolation:
private double[] InterpolateArray(double[] array, int newLength)
{
double[] result = new double[newLength];
result[0] = array[0];
result[newLength - 1] = array[array.Length - 1];
for (int i = 1; i < newLength - 1; i++)
{
double jd = ((double)i * (double)(array.Length - 1) / (double)(newLength - 1));
int j = (int)jd;
result[i] = array[j] + (array[j + 1] - array[j]) * (jd - (double)j);
}
return result;
}
Problem is that I have no idea how to interpolate Z coordinates of each point. Could that be done same way like X and Y coordinates? Or completely different approach is needed?
Edit: code for my Points struct:
public struct Points
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
public Points(double X, double Y, double Z)
{
this.X = X;
this.Y = Y;
this.Z = Z;
}
}
And code which does interpolation (or should do it at least):
public Points[,] Interpolate(Points[,] array, int newWidth, int newHeight)
{
Points[,] result = new Points[newWidth, newHeight];
double[] bufferBefore = new double[domes.GetLength(0)];
double[] bufferAfter = new double[newWidth];
for (int i = 0; i < domes.GetLength(1); i++)
{
for (int j = 0; j < domes.GetLength(0); j++)
{
bufferBefore[j] = domes[j, i].X;
}
bufferAfter = InterpolateArray(bufferBefore, newWidth);
for (int j = 0; j < newWidth; j++)
{
result[j, i].X = bufferAfter[j];
}
}
bufferBefore = new double[domes.GetLength(1)];
bufferAfter = new double[newHeight];
for (int i = 0; i < newWidth; i++)
{
for (int j = 0; j < domes.GetLength(1); j++)
{
bufferBefore[j] = result[i, j].Y;
}
bufferAfter = InterpolateArray(bufferBefore, newHeight);
for (int j = 0; j < newHeight; j++)
{
result[i, j].Y = bufferAfter[j];
}
}
return result;
}
I cannot see any way your current code is correct. In the second part you are doing bufferBefore[j] = result[i, j].Y;, but as far as I can see this has not been set anywhere before.
So when interpolating you need to interpolate all the values. So you would need to repeat the interpolation for each of x/y/z for each direction.
This however be done a bit simpler by implement the multiply operator for your point struct. This could allow you to do the interpolation for both x/y at once with code looking something like this:
public static Vector3 BilinearSample(this Vector3[,] self, in Vector2 point)
{
var xi = (int)Math.Floor(point.X);
var xi1 = xi + 1;
var xf = point.X - xi;
var yi = (int)Math.Floor(point.Y);
var yi1 = yi + 1;
var yf = point.Y - yi;
// You might need to add checks to ensure the sample is fully inside the image etc.
var v1 = self[xi, yi];
var v2 = self[xi1, yi];
var v3 = self[xi, yi1];
var v4 = self[xi1, yi1];
// Do the bilinear sample
var xfn1 = 1 - xf;
var v5 = v1 * xfn1 + v2 * xf;
var v6 = v3 * xfn1 + v4 * xf;
var result = v5 * (1 - yf) + v6 * yf;
return result;
}
I'm using System.Numerics instead of Point , but the principle is the same. Note that the above code would be identicalif you change the input/output type to Vector2 or double.
Also note that if the values represents direction or rotation you need to be careful, since the resulting directions might not be normalized after interpolation, and might even be zero.

Fast inversion of an axis of 3D data stored in a 1D array

I have a large dataset that represents a 3D image (approx 100,000,000 pixels). I want to invert the pixels along the 'z' axis of the image. My data is stored in a byte array where the data is ordered x, y, z (i.e [] = { (x=0,y,z=0), (x=1,y=0,z=0), (x=2,y=0,z=0) ...)
I can easily sort them using the following code, however I am looking to reduce computation time where possible (currently reporting around 7 seconds). I am considering using an array 'sort' function, but am not sure how to handle the indexing.
Here is my current code:
private int GetIndex(Image _image, int _x, int _y, int _z)
{
return (_z * _image.Size.X * _image.Size.Y) + (_y * _image.Size.X) + _x;;
}
private void InvertZ(Image _image)
{
for (int z = 0; z < _image.Size.Z/2; z++)
{
for (int y = 0; y < _image.Size.Y; y++)
{
for (int x = 0; x < _image.Size.X; x++)
{
int srcIndex = GetIndex(_image, x, y, z);
int destIndex = GetIndex(_image, x, y, _image.Size.Z - z - 1);
byte src = _image.Buffer[srcIndex];
byte dest = _image.Buffer[destIndex];
_image.Buffer[srcIndex] = dest;
_image.Buffer[destIndex] = src;
}
}
}
}
One solution is to copy each frame. Reduces the number of iterations drastically.
private void InvertZ(Image _image)
{
int frameSize = _image.Size.X * _image.Size.Y;
byte[] temp = new byte[frameSize];
for (int z = 0; z < _image.Size.Z / 2; z++)
{
int inverseZ = _image.Size.Z - z - 1;
Array.Copy(_image.Buffer, z * frameSize, temp, 0, frameSize);
Array.Copy(_image.Buffer, inverseZ * frameSize, _image.Buffer, z * frameSize, frameSize);
Array.Copy(temp, 0, _image.Buffer, inverseZ * frameSize, frameSize);
}
}
Runtime approx < 18 ms compared to 3175 ms.
This might be faster that your one loop solution even if it uses several loops, one for each axis.
There are 2 major speed enhancements (very common algorithm enhancements within image processing).
The Image is converted to a array for quick legwork
The index become partly precomputed within the the loops making sure the you calculate as much as possible as few times as possible. (no more use of the built-in thing in Image which is nice for one and another pixel but not suitable for the whole map)
I usually only do this work on 2d so the z axis is just added. it might be faster having it as the last loop. (fringe example running in 2d if y is before x then you loose about 30-40% speed because of the way memory/cache is built Src this happens at 3d as well (that's why I placed the z (levels/pages at the front))
Here is the code I would base my solution on.
private void InvertZ(Image _image)
{
byte[] array =imageToByteArray(_image);
int pageSize = _Image.Size.Y * _Image.Size.X;
for (int z = 0; z < _image.Size.Z/2; z++)
{
int level = z * pageSize;
int dstLevel = (_image.Size.Z - z - 1) * pageSize;
for (int x = 0; x < _image.Size.X; x++)
{
int Row = x*_Image.Size.Y;
int RowOnLevel = level + Row ;
int dstRowOnLevel = dstLevel + xRow;
for (int y = 0; y < _image.Size.Y; y++)
{
int srcIndex = RowOnLevel + y;
int destIndex = dstRowOnLevel + y;
byte tmpDest = array[destIndex];
array[destIndex] = array[srcIndex];
array[srcIndex] = tmpDest;
}
}
}
return byteArrayToImage(array);
}
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
You can use the fact that the array layout is like this
Z Length
==== ======
[0] x * y
[1] x * y
[2] x * y
...
[z-1] x * y
This allows us to greatly reduce index calculations. We can use a variation of the classic O(N) reverse algorithm like this
static void InvertZ(Image _image)
{
int len = _image.Size.X * _image.Size.Y;
for (int lo = 0, hi = (_image.Size.Z - 1) * len; lo < hi; lo += len, hi -= len)
for (int i = 0; i < len; i++)
Swap(ref _image.Buffer[lo + i], ref _image.Buffer[hi + i]);
}
static void Swap<T>(ref T a, ref T b) { var c = a; a = b; b = c; }

If Best Fit Straight Line the best method for prediction

I need to make prediction for a next point, based on given set of point samples on 2-d coordinate system.
I am using Best-Fit Straight Line method for such prediction.
Please let me know if there is method better than Best-Fit Straight Line?
My code is below:
public class LineEquation
{
public double m; //slope
public double c; //constant in y=mx+c
}
public class Point
{
public double x;
public double y;
}
public class BestFitLine
{
public Point[] points = new Point[7];
public void InputPoints(Point[] points)
{
for (int i = 0; i < points.Length; i++)
{
points[i] = new Point();
}
points[0].x = 12;
points[0].y = 13;
points[1].x = 22;
points[1].y = 23;
points[2].x = 32;
points[2].y = 33;
points[3].x = 42;
points[0].y = 23;
points[4].x = 52;
points[4].y = 33;
points[5].x = 62;
points[5].y = 63;
points[6].x = 72;
points[6].y = 63;
}
public LineEquation CalculateBestFitLine(Point[] points)
{
double constant = 0;
double slope=0;
for (int i = 0; i < points.Length - 1; i++)
{
for (int j = i + 1; j < points.Length; j++)
{
double m = (points[j].y - points[i].y) / (points[j].x - points[i].x);
double c = points[j].y - (m * points[j].x);
constant += c;
slope += m;
}
}
int lineCount =((points.Length-1)*points.Length)/2;
slope = slope / lineCount;
constant = constant / lineCount;
LineEquation eq = new LineEquation();
eq.c = constant;
eq.m = slope;
return eq;
}}
If your x coordinate is composed of dates, you can rely on generalized additive models with the following components :
- trend
- yearly profile
- weekly profile
- daily profile
GAM models are available in R, so I would advice you to use JRI in order to interface your java code with R.
Cheers
I think you could consider smoothing algorithms like Exponential Moving average to predict the near future data points,
http://en.wikipedia.org/wiki/Exponential_smoothing

keeping array in an array

i want to save kingarray[x1+1,y1-1],king array[x1+1,y1],etc in an array(ways that king in chess game can go).how can i do it?or if its not possible what do you suggest me to keep the ways that king can go?thanks
int[,] kingarray = new int[8, 8];
for (i = 0; i < 1; i++)
{
return kingarray[x1 + 1, y1];
}
for (i = 1; i > 0; i--)
{
return kingarray[x1 - 1, y1];
}
for (j = 0; j < 1; j++)
{
return kingarray[x1, y1 + 1];
}
for (j = 1; j > 0; j--)
{
return kingarray[x1, y1 - 1];
}
for (i = 0; i < 1; i++)
for (j = 1; j > 0; j--)
{
return kingarray[x1 + 1, y1 - 1];
}
for (i = 1; i > 0; i--)
for (j = 0; j < 1; j++)
{
return kingarray[x1 - 1, y1 + 1];
}
for (i = 0; i < 1; i++)
for (j = 0; j < 1; j++)
{
return kingarray[x1 + 1, y1 + 1];
}
for (i = 1; i > 0; i--)
for (j = 1; j > 0; j--)
{
return kingarray[x1 - 1, y1 - 1];
}
what do you suggest me to keep the ways that king can go?
This may not answer your question directly, and that you have already marked the correct answer. But just to answer the above.
Rather than keeping the all the positions a king can go, I would keep the positions it is allowed to go and calculate the possible routes during run-time.
For any piece(King, Pawn, etc), there are 8 places that it can move. Left, right, up, down, top-left, top-right, bottom-left, bottom-right. Based upon the type of piece, you can control the movement.
For You can create a ChessPiece class. Declare 8 positional flags, bool flags probably, that would define the possible positions that a piece can move.
Declare the number of blocks a piece can skip, for instance directions(; and drive the types from the ChessPiece and allow.
--EDIT--
For instance, following:
//Class that contains the position of the Piece over the Tile
class PiecePosition
{
//Set the bounds an image/vector can move.
public int X, Y;
public PiecePosition(int x, int y) { this.X = x; this.Y = y; }
public PiecePosition(int x, int y, int width, int height) { this.X = x; this.Y = y; }
}
//Base ChessPeice class that shall be used to drive all types of chess pieces.
//Sixteen pieces: one king, one queen, two rooks, two knights, two bishops, and eight pawns
//http://en.wikipedia.org/wiki/Chess
abstract class ChessPiece
{
public object Image;//This is an "optional" object that contains the Picture of the Peice,
//alternatively, it may contain vector of the image that you want
//to draw. Right now this is object is here just for the sake of
//understanding that you can use this object here to Draw() it
//based upon its position.
//Possible movements of the unhindered piece=8
protected const int MaxDirectionsCount = 8;
public enum PieceType { King, Pawn, SomeOtherType }//Types of chess peice.
public enum Moves { Up, Down, Left, Right, TopLeft, Etc }//Possible positions a piece can move
protected PieceType Type; //Contains type of piece
protected Moves MoveableDirections;//Shall contain the allowable directions
public List<PiecePosition> listPositions;//List of possible positions to be calculated during runtime
//Defines a piece can skip
protected int SkippableBlocks;
public abstract void PossiblePositions(PiecePosition CurrentPosition);//Calculates possible positions
public abstract void Draw();//Draws the piece
}
//The King Chess piece
//http://en.wikipedia.org/wiki/King_%28chess%29
class King : ChessPiece
{
//Constructor that sets the type of piece
public King()
{
//Set the directions a King can move.
base.MoveableDirections = Moves.Down | Moves.Left | Moves.Right;
base.Type = PieceType.King;
SkippableBlocks = 1; //Max a king can move is one block in the base.Directions set above.
}
//Calculates possible available positions to move to, during runtime; based upon current position.
public override void PossiblePositions(PiecePosition CurrentPosition)
{
//Calculate position
//Since you know this is king piece, you can calculate the possible positions
//And add that the list of possible positions.
//For instance, a King can move
int X = 0; int Y = 0;
for (int i = 0; i < MaxDirectionsCount; i++)
{
//Calculate directions.
if (base.MoveableDirections == Moves.Down) { X = CurrentPosition.X - 1; Y = CurrentPosition.Y; }
if (base.MoveableDirections == Moves.Up) { X = CurrentPosition.X + 1; Y = CurrentPosition.Y; }
//Rest of the directions go here...
//...Btw, what would you do for cross directions?
//One way could be to pass a Rectangle in the ChessTile(x,y,width,height) constructor
//Add to list of possible directions.
listPositions.Add(new PiecePosition(X, Y));
}
}
public override void Draw()
{
//You can actually draw/redraw using the Image object
//based upon the current/moved position.
}
}
Btw, if you just started writing the code, I would suggest you stop. Look around for Chess class designs first, and see if you want make sense out of Chess Objects. For instance, ChessBoard, Game, Players, Piece, Movements, AllowablePositions, etc.
Take a look at questions related to Chess/Google abit, and see if the questions/answers and your logic is already inline.
Array?
It is rather easy to determine a King's possible movement.
class position { public int x, y }
...
public ArrayList<position> KingPossibleMove(position current)
{
var list = new ArrayList();
if (current.x>0) {
list.add(new position() { x= current.x - 1, y = current.y });
if (current.x<8) {
list.add(new position() { x= current.x + 1, y = current.y });
// The rest follows, try to determine if the move is within bound
// you can also look for if the move will cause immediate checkmate.
return list;
}
int[,][] declares a 1D array containing a 2D array of int. Is that what you want?
And the kingmoves can simply be calculated as:
IEnumerable<Position> ValidKingTargets(Position p)
{
int top=Math.Max(0,y-1);
int left=Math.Max(0,x-1);
int bottom=Math.Min(8,y+2);
int right=Math.Min(8,x+2);
for(int y=top;y<bottom;y++)
for(int x=left;x<right;x++)
if(x!=p.X || y!=p.Y)
yield return new Position(x,y);
}

Categories