//Convolution Laplacian function //calculates sum of all neighbours and cell after they are * by a constant public static double ConvolutionLaplacian(Cell[] neighbours, double value, bool AorB) { double sumOfNeighbours = 0; for (int i = 0; i < neighbours.Length; i++) { if ((i == 0) || (i == 2) || (i == 4) || (i == 6)) { if (AorB == true) { sumOfNeighbours += (neighbours[i].CurrentAValue * 0.2); } else { sumOfNeighbours += (neighbours[i].CurrentBValue * 0.2); } } else { if (AorB == true) { sumOfNeighbours += (neighbours[i].CurrentAValue * 0.05); } else { sumOfNeighbours += (neighbours[i].CurrentBValue * 0.05); } } } return (value*-1) + sumOfNeighbours; }
//Grey-Scott Equation for B public double CalcAValue(Cell cell, Cell[] neighbours) { //lapFunc is method call for the laplacian function double calc1 = diffA * lapFunc(neighbours, cell.CurrentAValue, true); double calc2 = cell.CurrentAValue * (cell.CurrentBValue * cell.CurrentBValue); double calc3 = feedA * (1 - cell.CurrentAValue); double returnValue = cell.CurrentAValue + calc1 - calc2 + calc3; if (returnValue < 0) { returnValue = 0; } else if (returnValue > 1) { returnValue = 1; } return returnValue; }
// Delta means Laplacian function //calculates difference between average of the neighbours and the current cell public static double DeltaMeansLaplacian(Cell[] neighbours, double value, bool AorB) { double averageOfNeighbours = 0; for (int i = 0; i < neighbours.Length; i++) { if (AorB == true) { averageOfNeighbours += neighbours[i].CurrentAValue; } else { averageOfNeighbours += neighbours[i].CurrentBValue; } } averageOfNeighbours /= neighbours.Length; return averageOfNeighbours -= value; }
//Perpendicular Laplacian function //calculates sum of neighbours the gets the difference between that and 4* the cell //then * by rh which is a biology constant public static double PerpendicularLaplacian(Cell[] neighbours, double value, bool AorB) { double h = 2.5 / 127.0; double rh = 1.0 / h / h; double sumOfNeighboursX = 0; for (int i = 0; i < neighbours.Length; i++) { if((i == 0)||(i == 2)||(i == 4)||(i == 6)) { if (AorB == true) { sumOfNeighboursX += neighbours[i].CurrentAValue; } else { sumOfNeighboursX += neighbours[i].CurrentBValue; } } } return rh * (sumOfNeighboursX - (4 * value)); }
//================================ //Inital setup methods for the gid //================================ //sets up the initial grid public void InitialGrid() { //fill grid with initial cells for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { grid[i, j] = new Cell(gridCanvas, new Point(gridBounds.X + (j * cellSize), gridBounds.Y + (i * cellSize)), colourScheme, cellSize); } } //seed the grid for (int i = gridSize / 4; i < gridSize / 1.4; i++) { for (int j = gridSize / 4; j < gridSize / 1.4; j++) { grid[i, j].CurrentBValue = 1; grid[i, j].CurrentAValue = 0; } } }
//goes through the grid calculating the next values for each cell public void GetCellsNextValues() { for (int i = 0; i < grid.GetLength(0); i++) { for (int j = 0; j < grid.GetLength(1); j++) { Cell currentCell = grid[i,j]; //turns the neighbour points held in each cell into the cells that they are Point[] neighbours = currentCell.CellNeighbours; Cell[] cellNeighbours = new Cell[neighbours.Length]; for(int k = 0; k < neighbours.Length; k++) { cellNeighbours[k] = grid[neighbours[k].X, neighbours[k].Y]; } currentCell.NextAValue = CalcAValue(currentCell, cellNeighbours); currentCell.NextBValue = CalcBValue(currentCell, cellNeighbours); } } }
//Grey-Scott Equation for B public double CalcBValue(Cell cell, Cell[] neighbours) { //lapFunc is method call for the laplacian function double calc1 = diffB * lapFunc(neighbours, cell.CurrentBValue, false); double calc2 = cell.CurrentAValue * (cell.CurrentBValue * cell.CurrentBValue); double calc3 = (killB + feedA) * cell.CurrentBValue; double returnValue = cell.CurrentBValue + calc1 + calc2 - calc3; if (returnValue < 0) { returnValue = 0; } else if (returnValue > 1) { returnValue = 1; } return returnValue; }