private List <GrainModel> GetNonInitialGrainsWithMaxCount(GrainCellModel grainCell) { var grainsCounts = grainCell.NeighboringCells.StatesCounts; var grainsWithMaxCount = new List <GrainModel>(); int maxCount = 0; foreach (var grainCount in grainsCounts) { if (grainCount.Value > maxCount && grainCount.Key != ZeroState) { maxCount = grainCount.Value; } } foreach (var grainCount in grainsCounts) { if (grainCount.Value == maxCount && grainCount.Key != ZeroState) { grainsWithMaxCount.Add((GrainModel)grainCount.Key); } } return(grainsWithMaxCount); }
private List <ICell> GetGrainCellsWithCenterOfMassWithinARadiusForAbsorbingBc(GrainCellModel centerGrainCell, int radius, List <List <ICell> > cellsState) { if (radius <= 0) { throw new ArgumentException("Radius must be grater than 0"); } if (radius > RowCount / 2 || radius > ColumnCount / 2) { throw new ArgumentException("Radius must be smaller than grid size"); } List <ICell> grainCellsWithinARadius = new List <ICell>(); GrainCellModel outsideGrainCell = new GrainCellModel((GrainModel)ZeroState); GrainCellModel grainCellInSquare; int upperLeftGrainCellRow = centerGrainCell.RowNumber - radius; int upperLeftGrainCellColumn = centerGrainCell.ColumnNumber - radius; for (int row = upperLeftGrainCellRow; row <= upperLeftGrainCellRow + 2 * radius; row++) { if (row >= -1 && row <= RowCount) { for (int column = upperLeftGrainCellColumn; column <= upperLeftGrainCellColumn + 2 * radius; column++) { if (column >= -1 && column <= ColumnCount) { if (row == -1 || row == RowCount || column == -1 || column == ColumnCount) { grainCellInSquare = outsideGrainCell; } else { grainCellInSquare = (GrainCellModel)cellsState[row][column]; } if (grainCellInSquare != centerGrainCell) { double distanceBetweenCentersOfMass = Math.Sqrt( Math.Pow(grainCellInSquare.GlobalCenterOfMass.X - centerGrainCell.GlobalCenterOfMass.X, 2) + Math.Pow(grainCellInSquare.GlobalCenterOfMass.Y - centerGrainCell.GlobalCenterOfMass.Y, 2) ); if (distanceBetweenCentersOfMass <= radius) { grainCellsWithinARadius.Add(grainCellInSquare); } } } } } } return(grainCellsWithinARadius); }
private List <ICell> GetGrainCellsWithCenterOfMassWithinARadiusForPeriodicBc(GrainCellModel centerGrainCell, int radius, List <List <ICell> > cellsState) { if (radius <= 0) { throw new ArgumentException("Radius must be grater than 0"); } if (radius > RowCount / 2 || radius > ColumnCount / 2) { throw new ArgumentException("Radius must be smaller than grid size"); } List <ICell> grainCellsWithinARadius = new List <ICell>(); var upperLeftGrainCell = GetUpperLeftGrainCellFromSquarePerimiter(centerGrainCell, radius); double centerGrainCellLocalX = centerGrainCell.CenterOfMass.X + radius + centerGrainCell.Width / 2.0; double centerGrainCellLocalY = centerGrainCell.CenterOfMass.Y - radius - centerGrainCell.Height / 2.0; for (int movesMadeToNextRowCount = 0, globalRow = upperLeftGrainCell.RowNumber, localRow = 0; movesMadeToNextRowCount < 2 * radius + 1; movesMadeToNextRowCount++, globalRow++, localRow++) { if (globalRow >= RowCount) { globalRow = 0; } for (int movesMadeToNextColumnCount = 0, globalColumn = upperLeftGrainCell.ColumnNumber, localColumn = 0; movesMadeToNextColumnCount < 2 * radius + 1; movesMadeToNextColumnCount++, globalColumn++, localColumn++) { if (globalColumn >= ColumnCount) { globalColumn = 0; } var grainCellInSquare = (GrainCellModel)cellsState[globalRow][globalColumn]; if (grainCellInSquare != centerGrainCell) { double grainCellInSquareLocalX = grainCellInSquare.CenterOfMass.X + localColumn + grainCellInSquare.Width / 2.0; double grainCellInSquareLocalY = grainCellInSquare.CenterOfMass.Y - localRow - grainCellInSquare.Height / 2.0; double distanceBetweenCentersOfMass = Math.Sqrt( Math.Pow(grainCellInSquareLocalX - centerGrainCellLocalX, 2) + Math.Pow(grainCellInSquareLocalY - centerGrainCellLocalY, 2) ); if (distanceBetweenCentersOfMass <= radius) { grainCellsWithinARadius.Add(grainCellInSquare); } } } } return(grainCellsWithinARadius); }
private bool IsNoGrainWithinARadiusForPeriodicBc(GrainCellModel centerCell, int radius) { if (radius <= 0) { throw new ArgumentException("Radius must be grater than 0"); } var upperLeftGrainCell = GetUpperLeftGrainCellFromSquarePerimiter(centerCell, radius); for (int rowInSquarePerimiter = 0, y = radius; rowInSquarePerimiter < 2 * radius + 1; rowInSquarePerimiter++, y--) { int rowInGrid = upperLeftGrainCell.RowNumber + rowInSquarePerimiter; if (rowInGrid < 0) { rowInGrid += RowCount; } if (rowInGrid >= RowCount) { rowInGrid -= RowCount; } for (int columnInSquarePerimiter = 0, x = -1 * radius; columnInSquarePerimiter < 2 * radius + 1; columnInSquarePerimiter++, x++) { int columnInGrid = upperLeftGrainCell.ColumnNumber + columnInSquarePerimiter; if (columnInGrid < 0) { columnInGrid += ColumnCount; } if (columnInGrid >= ColumnCount) { columnInGrid -= ColumnCount; } var cellInSquare = CurrentState[rowInGrid][columnInGrid]; double distanceFromCenter = Math.Pow(x, 2) + Math.Pow(y, 2); if (distanceFromCenter <= Math.Pow(radius + 0.5, 2)) { if (cellInSquare.State != ZeroState) { return(false); } } } } return(true); }
private void SetCellGrainToRandomFromNeighborhood(GrainCellModel grainCell) { CreateNewStaticRandom(); var grainsCounts = grainCell.NeighboringCells.StatesCounts; do { int randomNeighboringGrainInt = staticRandom.Next(grainsCounts.Count); grainCell.State = grainsCounts.ElementAt(randomNeighboringGrainInt).Key; } while (grainCell.State == ZeroState); }
private List <ICell> GetGrainCellsWithinARadiusForPeriodicBc(GrainCellModel centerGrainCell, int radius, List <List <ICell> > cellsState) { if (radius <= 0) { throw new ArgumentException("Radius must be grater than 0"); } if (radius > RowCount / 2 || radius > ColumnCount / 2) { throw new ArgumentException("Radius must be smaller than grid size"); } List <ICell> grainCellsWithinARadius = new List <ICell>(); var upperLeftGrainCell = GetUpperLeftGrainCellFromSquarePerimiter(centerGrainCell, radius); for (int movesMadeToNextRowCount = 0, row = upperLeftGrainCell.RowNumber, y = radius; movesMadeToNextRowCount < 2 * radius + 1; movesMadeToNextRowCount++, row++, y--) { if (row >= RowCount) { row = 0; } for (int movesMadeToNextColumnCount = 0, column = upperLeftGrainCell.ColumnNumber, x = -1 * radius; movesMadeToNextColumnCount < 2 * radius + 1; movesMadeToNextColumnCount++, column++, x++) { if (column >= ColumnCount) { column = 0; } var grainCellInSquare = cellsState[row][column]; if (grainCellInSquare != centerGrainCell) { double distanceFromCenter = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)); if (distanceFromCenter <= radius + 0.5) { grainCellsWithinARadius.Add(grainCellInSquare); } } } } return(grainCellsWithinARadius); }
private bool IsNoGrainWithinARadius(GrainCellModel centerCell, int radius) { if (radius <= 0) { throw new ArgumentException("Radius must be grater than 0"); } if (BoundaryCondition == BoundaryConditionModel.Periodic) { return(IsNoGrainWithinARadiusForPeriodicBc(centerCell, radius)); } else { return(IsNoGrainWithinARadiusForAbsorbingBc(centerCell, radius)); } }
private bool IsNoGrainWithinARadiusForAbsorbingBc(GrainCellModel centerCell, int radius) { if (radius <= 0) { throw new ArgumentException("Radius must be grater than 0"); } int upperLeftGrainCellRow = centerCell.RowNumber - radius; int upperLeftGrainCellColumn = centerCell.ColumnNumber - radius; for (int row = upperLeftGrainCellRow, y = radius; row <= upperLeftGrainCellRow + 2 * radius; row++, y--) { if (row >= 0 && row < RowCount) { for (int column = upperLeftGrainCellColumn, x = -1 * radius; column <= upperLeftGrainCellColumn + 2 * radius; column++, x++) { if (column >= 0 && column < ColumnCount) { var cellInSquare = CurrentState[row][column]; double distanceFromCenter = Math.Pow(x, 2) + Math.Pow(y, 2); if (distanceFromCenter <= Math.Pow(radius + 0.5, 2)) { if (cellInSquare.State != ZeroState) { return(false); } } } } } } return(true); }
private GrainModel GetGrainToExpand(GrainCellModel grainCell) { CreateNewStaticRandom(); var grainsWithMaxCount = GetNonInitialGrainsWithMaxCount(grainCell); if (grainsWithMaxCount.Any()) { if (grainsWithMaxCount.Count() == 1) { return(grainsWithMaxCount.First()); } else { return(grainsWithMaxCount.ElementAt(staticRandom.Next(grainsWithMaxCount.Count()))); } } else { return((GrainModel)ZeroState); } }
private ICell GetUpperLeftGrainCellFromSquarePerimiter(GrainCellModel centerCell, int radius) { if (radius <= 0) { throw new ArgumentException("Radius must be grater than 0"); } int upperLeftGrainCellRow = centerCell.RowNumber - radius; int upperLeftGrainCellColumn = centerCell.ColumnNumber - radius; if (upperLeftGrainCellRow < 0) { upperLeftGrainCellRow += RowCount; } if (upperLeftGrainCellColumn < 0) { upperLeftGrainCellColumn += ColumnCount; } return(CurrentState[upperLeftGrainCellRow][upperLeftGrainCellColumn]); }
private void AddNeighboringCellsToCellsState(List <List <ICell> > cellsState) { GrainCellModel outsideCell = new GrainCellModel((GrainModel)ZeroState); for (int row = 0, cellId = 0; row < RowCount; row++) { for (int column = 0; column < ColumnCount; column++, cellId++) { if (cellsState[row][column].State == ZeroState) { switch (NeighborhoodType) { case CellNeighborhoodTypeModel.VonNeumann: case CellNeighborhoodTypeModel.Moore: case CellNeighborhoodTypeModel.RandomPentagonal: case CellNeighborhoodTypeModel.LeftHexagonal: case CellNeighborhoodTypeModel.RightHexagonal: case CellNeighborhoodTypeModel.RandomHexagonal: switch (BoundaryCondition) { case BoundaryConditionModel.Absorbing: cellsState[row][column].NeighboringCells = new EightSidedGrainCellNeighborhood { Top = row == 0 ? outsideCell : cellsState[row - 1][column], TopRight = row == 0 || column == ColumnCount - 1 ? outsideCell : cellsState[row - 1][column + 1], Right = column == ColumnCount - 1 ? outsideCell : cellsState[row][column + 1], BottomRight = row == RowCount - 1 || column == ColumnCount - 1 ? outsideCell : cellsState[row + 1][column + 1], Bottom = row == RowCount - 1 ? outsideCell : cellsState[row + 1][column], BottomLeft = row == RowCount - 1 || column == 0 ? outsideCell : cellsState[row + 1][column - 1], Left = column == 0 ? outsideCell : cellsState[row][column - 1], TopLeft = row == 0 || column == 0 ? outsideCell : cellsState[row - 1][column - 1], Type = NeighborhoodType }; break; case BoundaryConditionModel.Periodic: cellsState[row][column].NeighboringCells = new EightSidedGrainCellNeighborhood { Top = cellsState[row == 0 ? RowCount - 1 : row - 1][column], TopRight = cellsState[row == 0 ? RowCount - 1 : row - 1][column == ColumnCount - 1 ? 0 : column + 1], Right = cellsState[row][column == ColumnCount - 1 ? 0 : column + 1], BottomRight = cellsState[row == RowCount - 1 ? 0 : row + 1][column == ColumnCount - 1 ? 0 : column + 1], Bottom = cellsState[row == RowCount - 1 ? 0 : row + 1][column], BottomLeft = cellsState[row == RowCount - 1 ? 0 : row + 1][column == 0 ? ColumnCount - 1 : column - 1], Left = cellsState[row][column == 0 ? ColumnCount - 1 : column - 1], TopLeft = cellsState[row == 0 ? RowCount - 1 : row - 1][column == 0 ? ColumnCount - 1 : column - 1], Type = NeighborhoodType }; break; } break; case CellNeighborhoodTypeModel.Radial: switch (BoundaryCondition) { case BoundaryConditionModel.Absorbing: cellsState[row][column].NeighboringCells = new RadialGrainCellNeighborhood( GetGrainCellsWithinARadiusForAbsorbingBc( (GrainCellModel)cellsState[row][column], CellNeighborhoodRadius, cellsState), NeighborhoodType); break; case BoundaryConditionModel.Periodic: cellsState[row][column].NeighboringCells = new RadialGrainCellNeighborhood( GetGrainCellsWithinARadiusForPeriodicBc( (GrainCellModel)cellsState[row][column], CellNeighborhoodRadius, cellsState), NeighborhoodType); break; } break; case CellNeighborhoodTypeModel.RadialWithCenterOfMass: switch (BoundaryCondition) { case BoundaryConditionModel.Absorbing: cellsState[row][column].NeighboringCells = new RadialGrainCellNeighborhood( GetGrainCellsWithCenterOfMassWithinARadiusForAbsorbingBc( (GrainCellModel)cellsState[row][column], CellNeighborhoodRadius, cellsState), NeighborhoodType); break; case BoundaryConditionModel.Periodic: cellsState[row][column].NeighboringCells = new RadialGrainCellNeighborhood( GetGrainCellsWithCenterOfMassWithinARadiusForPeriodicBc( (GrainCellModel)cellsState[row][column], CellNeighborhoodRadius, cellsState), NeighborhoodType); break; } break; } } } } }