예제 #1
0
        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--;
            }
        }
예제 #2
0
 private Tile GetRight(Tile t)
 {
     return(mapData.Tiles[MathHelpers.Mod(t.X + 1, Width), t.Y]);
 }
예제 #3
0
 private Tile GetTop(Tile t)
 {
     return(mapData.Tiles[t.X, MathHelpers.Mod(t.Y - 1, Height)]);
 }
예제 #4
0
 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;
                }
            }
        }