public double Get(double x, double y) { if (Mode == VoronoiMode.FrontierDetection) { var result = GetCells(x, y, 2); //Return the distance between the two nearest points return(result[1].DistanceSquared - result[0].DistanceSquared); } else { x *= Frequency; y *= Frequency; if (NoiseBorder != null) { x += NoiseBorder.Get(x, 0); y += NoiseBorder.Get(0, y); } int xInt = (x > 0.0 ? (int)x : (int)x - 1); int yInt = (y > 0.0 ? (int)y : (int)y - 1); double minDist = double.MaxValue; int xCell = 0; int yCell = 0; // Inside each unit cube, there is a seed point at a random position. Go // through each of the nearby cubes until we find a cube with a seed point // that is closest to the specified position. for (int yCur = yInt - 2; yCur <= yInt + 2; yCur++) { for (int xCur = xInt - 2; xCur <= xInt + 2; xCur++) { // Calculate the position and distance to the seed point inside of // this unit cube. double xPos = xCur + (ValueNoise(xCur, yCur, Seed + 1) * Noisiness); double yPos = yCur + (ValueNoise(xCur, yCur, Seed + 2) * Noisiness); double xDist = xPos - x; double yDist = yPos - y; double dist = xDist * xDist + yDist * yDist; if (dist < minDist) { // This seed point is closer to any others found so far, so record minDist = dist; xCell = xCur; yCell = yCur; } } } // Return the calculated distance with the displacement value applied. return(ValueNoise(xCell, yCell, Seed)); } }
public VoronoiCell[] GetCells(double x, double y, int nbrCells = 4) { VoronoiCell[] cells = new VoronoiCell[nbrCells]; //Init result for (int i = 0; i < nbrCells; i++) { cells[i] = new VoronoiCell() { DistanceSquared = double.MaxValue }; } x *= Frequency; y *= Frequency; if (NoiseBorder != null) { x += NoiseBorder.Get(x, 0); y += NoiseBorder.Get(0, y); } int xInt = (x > 0.0 ? (int)x : (int)x - 1); int yInt = (y > 0.0 ? (int)y : (int)y - 1); // Inside each unit cube, there is a seed point at a random position. Go // through each of the nearby cubes until we find a cube with a seed point // that is closest to the specified position. int highestFreeCellsIndex = 0; for (int yCur = yInt - 2; yCur <= yInt + 2; yCur++) { for (int xCur = xInt - 2; xCur <= xInt + 2; xCur++) { // Calculate the position and distance to the seed point inside of // this unit cube. double xPos = xCur + (ValueNoise(xCur, yCur, Seed) * Noisiness); double yPos = yCur + (ValueNoise(xCur, yCur, Seed + 1) * Noisiness); double xDist = xPos - x; double yDist = yPos - y; double dist = xDist * xDist + yDist * yDist; for (int c = 0; c < nbrCells; c++) { if (dist < cells[c].DistanceSquared) { if (c < highestFreeCellsIndex) { //Shift array to right if needed Array.Copy(cells, c, cells, c + 1, cells.Length - c - 1); } //Add new item at correct place (keeping the cells ordered in the list) cells[c].DistanceSquared = dist; cells[c].CellId = new Vector2I(xCur, yCur); highestFreeCellsIndex++; break; } } } } // Return the calculated distance with the displacement value applied. return(cells); }