private void AddMoisture(float[,] moistureData, Tile t, int radius) { int startx = MathHelpers.Mod(t.X - radius, Width); int endx = MathHelpers.Mod(t.X + radius, Width); Vector2 center = new Vector2(t.X, t.Y); int curr = radius; while (curr > 0) { int x1 = MathHelpers.Mod(t.X - curr, Width); int x2 = MathHelpers.Mod(t.X + curr, Width); int y = t.Y; AddMoisture(moistureData, mapData.Tiles[x1, y], 0.025f / (center - new Vector2(x1, y)).Magnitude); for (int i = 0; i < curr; i++) { AddMoisture(moistureData, mapData.Tiles[x1, MathHelpers.Mod(y + i + 1, Height)], 0.025f / (center - new Vector2(x1, MathHelpers.Mod(y + i + 1, Height))).Magnitude); AddMoisture(moistureData, mapData.Tiles[x1, MathHelpers.Mod(y - (i + 1), Height)], 0.025f / (center - new Vector2(x1, MathHelpers.Mod(y - (i + 1), Height))).Magnitude); AddMoisture(moistureData, mapData.Tiles[x2, MathHelpers.Mod(y + i + 1, Height)], 0.025f / (center - new Vector2(x2, MathHelpers.Mod(y + i + 1, Height))).Magnitude); AddMoisture(moistureData, mapData.Tiles[x2, MathHelpers.Mod(y - (i + 1), Height)], 0.025f / (center - new Vector2(x2, MathHelpers.Mod(y - (i + 1), Height))).Magnitude); } curr--; } }
private Tile GetRight(Tile t) { return(mapData.Tiles[MathHelpers.Mod(t.X + 1, Width), t.Y]); }
private Tile GetTop(Tile t) { return(mapData.Tiles[t.X, MathHelpers.Mod(t.Y - 1, Height)]); }
private Tile GetBottom(Tile t) { return(mapData.Tiles[t.X, MathHelpers.Mod(t.Y + 1, Height)]); }
void AssignInitialPlateProperties() { int northWorldAxisX = random.Next(Width); int northWorldAxisY = random.Next(Height / 2); int southWorldAxisY = (Height / 2) + northWorldAxisY; int southWorldAxisX = Width - northWorldAxisX; if (southWorldAxisX < 0) { southWorldAxisX = Width - southWorldAxisX; } if (southWorldAxisX >= Width) { southWorldAxisX = southWorldAxisX - Width; } Point northPole = new Point(northWorldAxisX, northWorldAxisY); Point southPole = new Point(southWorldAxisX, southWorldAxisY); Vector2 equatorPointer = ((southPole - northPole) / 2); Point equatorPoint = new Point(equatorPointer.X, equatorPointer.Y); float equatorSlopeY1 = MathHelpers.Solve_Y_ForLineBetweenTwoPoints(northPole.X, northPole.Y, southPole.X, southPole.Y, 0); float equatorSlopeY2 = MathHelpers.Solve_Y_ForLineBetweenTwoPoints(northPole.X, northPole.Y, southPole.X, southPole.Y, 1); float equatorSlope = (equatorSlopeY2 - equatorSlopeY1) / (1 - 0); //float distanceBetweenPoles = (float)Math.Sqrt(Math.Pow((northWorldAxisX - southWorldAxisX), 2) + Math.Pow((northWorldAxisY - southWorldAxisY), 2)); for (int i = 0; i < NumberOfPlates; i++) { // Between -2 and 2 by generating a number >= 0 && < 5, then subtracting 2 //int plateHeight = random.Next(5) - 2; //float plateHeight = random.Next(5) / 4.0f; float plateHeight = (float)random.NextDouble(); float plateSpinSpeedIncrement = (float)random.NextDouble() / 10; bool plateSpinClockwise = random.Next(0, 2) == 1 ? true : false; var plateTiles = mapData.Tiles.AsList().Where(t => t.PlateId == i); var plateCenter = plateTiles.First(x => x.IsPlateCenter); Point plateCenterPoint = new Point(plateCenter.X, plateCenter.Y); foreach (Tile tile in plateTiles) { // set height tile.PlateHeight = (float)plateHeight; tile.HeightValue = (float)plateHeight; Point tilePoint = new Point(tile.X, tile.Y); // TODO, this needs to be changed to use spherical coordinates // set Global Drift // TODO, real maths might transform the axis.. normal line from pole to equator, rotate so it's straight, then project the tile to that line, // y value compared to distance of line would tell gradient // Find closest pole, then find distance between closest pole and equator float distToNorth = Math.Abs(MathHelpers.GetDistanceBetweenTwoPoints(northWorldAxisX, northWorldAxisY, tile.X, tile.Y)); float distToSouth = Math.Abs(MathHelpers.GetDistanceBetweenTwoPoints(southWorldAxisX, southWorldAxisY, tile.X, tile.Y)); Point referencePole = (distToNorth < distToSouth) ? northPole : southPole; // Lienar gradient for Global Drift from pole to equator.. dist will be 0 - 1 so just use that Point projectedPt = MathHelpers.Project(referencePole, equatorPoint, new Point(tile.X, tile.Y)); float distToEquator = (projectedPt - referencePole).Magnitude / (equatorPoint - referencePole).Magnitude; tile.GlobalDriftStrength = distToEquator; // Get vector parallel to equator for direction.. rotation will be clockwise around axis, so x - 1 is next point //Point nextTilePoint = new Point((1 / equatorSlope) + tilePoint.X, tilePoint.Y + 1); float nextTilePointX = tilePoint.X - 1; float nextTilePointY = equatorSlope * (nextTilePointX - tilePoint.X) + tilePoint.Y; Point nextTilePoint = new Point(nextTilePointX, nextTilePointY); tile.GlobalDriftDirection = (nextTilePoint - tilePoint).UnitVector; tile.PlateRotationStrength = plateSpinSpeedIncrement * MathHelpers.GetDistanceBetweenTwoPoints(plateCenterPoint, tilePoint); Vector2 vectorFromCenterToPoint = tilePoint - plateCenterPoint; Vector2 perpendicularVector = new Vector2(vectorFromCenterToPoint.Second, vectorFromCenterToPoint.First * -1); if (!plateSpinClockwise) { perpendicularVector = perpendicularVector * -1; } tile.PlateRotationDirection = perpendicularVector.UnitVector; } } }