Пример #1
0
 internal void UpdateClimateFileReferenceCount()
 {
     if (ClimateData != null)
     {
         ClimateData.DecrementReferenceCount();
     }
 }
    /// <summary>
    /// Создать лист информации о климате
    /// </summary>
    void CreateClimate()
    {
        climate.Clear();
        nextClimate.Clear();
        ClimateData initialData = new ClimateData();
        initialData.moisture = startingMoisture;
        ClimateData clearData = new ClimateData();
        for (int i = 0; i < cellCount; i++)
        {
            climate.Add(initialData);
            nextClimate.Add(clearData);
        }

        //добавляем облака из воды(40 циклов для симуляции)
        for (int cycle = 0; cycle < 40; cycle++)
        {
            for (int i = 0; i < cellCount; i++)
            {
                EvolveClimate(i);
            }
            List<ClimateData> swap = climate;
            climate = nextClimate;
            nextClimate = swap;
        }
    }
Пример #3
0
    /// <summary>
    /// 创建每个格子的气候
    /// </summary>
    void CreateClimate()
    {
        climate.Clear();
        nextClimate.Clear();
        ClimateData initialData = new ClimateData();

        initialData.moisture = startingMoisture;                        // 每个格子初始化一个湿度
        ClimateData clearData = new ClimateData();

        for (int i = 0; i < cellCount; i++)
        {
            climate.Add(initialData);
            nextClimate.Add(clearData);
        }

        // 暂定四十个周期
        for (int cycle = 0; cycle < 40; cycle++)
        {
            for (int i = 0; i < cellCount; i++)
            {
                EvolveClimate(i);
            }

            // 完成一周期的演变之后把最新的数据赋值给当前列表。
            List <ClimateData> swap = climate;
            climate     = nextClimate;
            nextClimate = swap;
        }
    }
Пример #4
0
        public ActionResult GetCurrentStatus()
        {
            // TemperatureData.Instance().currentDashModel = new DashboardModel(5, 6, "June 28, 2019", "9:54");
            ClimateModel dm = ClimateData.Instance().currentClimateModel;

            return(Json(dm));
        }
Пример #5
0
    void SetClimateData(int cellIndex, float moisture, float clouds)
    {
        TriDirection d = TriDirection.VERT;
        TriCell      current, k;
        ClimateData  t;

        current = k = grid.GetCell(cellIndex);
        for (int i = 0; i < 6; i++)
        {
            if (!k)
            {
                break;
            }

            t                = new ClimateData();
            t.moisture       = moisture;
            t.clouds         = clouds;
            climate[k.Index] = t;

            k = k.GetNeighbor(d);
            if (current.inverted)
            {
                d = d.Next();
            }
            else
            {
                d = d.Previous();
            }
        }
    }
Пример #6
0
    void CreateClimate()
    {
        climate.Clear();
        nextClimate.Clear();

        ClimateData initialData = new ClimateData();         // Initial buffer

        initialData.moisture = StartingMoisture;
        ClimateData clearData = new ClimateData();         // Next buffer

        for (int i = 0; i < cellCount; i++)
        {
            climate.Add(initialData);
            nextClimate.Add(clearData);
        }

        // * Number of water cycles is 40, the more cycles the more refined the result
        for (int cycle = 0; cycle < 40; cycle++)
        {
            for (int i = 0; i < cellCount; i++)
            {
                EvolveClimate(i);
            }

            List <ClimateData> swap = climate;
            climate     = nextClimate;
            nextClimate = swap;
        }
    }
        private void CreateClimate()
        {
            climate.Clear();
            nextClimate.Clear();
            var initialData = new ClimateData {
                Moisture = StartingMoisture
            };
            var clearData = new ClimateData();

            for (var i = 0; i < cellCount; i++)
            {
                climate.Add(initialData);
                nextClimate.Add(clearData);
            }

            for (var cycle = 0; cycle < 40; cycle++)
            {
                for (var i = 0; i < cellCount; i++)
                {
                    EvolveClimate(i);
                }
                var swap = climate;
                climate     = nextClimate;
                nextClimate = swap;
            }
        }
Пример #8
0
    public void CreateClimate()
    {
        HexaoidClimateEvolution = true;
        climate.Clear();
        nextClimate.Clear();
        ClimateData initialData = new ClimateData();

        initialData.moisture = startingMoisture;
        ClimateData clearData = new ClimateData();

        for (int i = 0; i < cellCount; i++)
        {
            climate.Add(initialData);
            nextClimate.Add(clearData);
        }
        for (int cycle = 0; cycle < 40; cycle++)
        {
            for (int i = 0; i < cellCount; i++)
            {
                EvolveClimateCell(i);
            }
            List <ClimateData> swap = climate;
            climate     = nextClimate;
            nextClimate = swap;
        }
    }
Пример #9
0
    private void CreateClimate()
    {
        m_climateData.Clear();
        m_nextClimateData.Clear();

        ClimateData initialClimateData = new ClimateData();
        ClimateData clearClimateData   = new ClimateData();

        initialClimateData.moisture = StartingMoisture;
        foreach (HexCell hexCell in HexGrid.GetHexCells())
        {
            m_climateData.Add(initialClimateData);
            m_nextClimateData.Add(clearClimateData);
        }

        for (int i = 0; i < 40; ++i)
        {
            foreach (HexCell hexCell in HexGrid.GetHexCells())
            {
                EvolveClimate(hexCell);
            }
            List <ClimateData> swap = m_climateData;
            m_climateData     = m_nextClimateData;
            m_nextClimateData = swap;
        }
    }
Пример #10
0
    // Start is called before the first frame update
    public void Awake()
    {
        lg = GameObject.Find("Generator").GetComponent <LandGeneration>();
        Dictionary <Climate, ClimateData> allData = JsonConvert.DeserializeObject <Dictionary <Climate, ClimateData> >(File.ReadAllText("ClimateData.json"));

        cd = allData[c];
    }
Пример #11
0
        public async Task ProcessNodeData([FromServices] INodeServices nodeServices)
        {
            var climateDataRaw = await nodeServices.InvokeExportAsync <ClimateDataRaw[]>(VeriSureAppFilePath, "sendClimateData");

            var alarmData = await nodeServices.InvokeExportAsync <AlarmStatus>(VeriSureAppFilePath, "sendAlarmStatus");

            ClimateData[] climateData = new ClimateData[climateDataRaw.Length];

            for (int i = 0; i < climateDataRaw.Length; i++)
            {
                climateData[i]             = new ClimateData();
                climateData[i].Temperature = float.Parse(climateDataRaw[i].Temperature.Remove(climateDataRaw[i].Temperature.IndexOf('&')));
                if (climateDataRaw[i].Humidity.Equals(string.Empty))
                {
                    climateData[i].Humidity = 0;
                }
                else
                {
                    climateData[i].Humidity = float.Parse(climateDataRaw[i].Humidity.Remove(climateDataRaw[i].Humidity.IndexOf('%')));
                }
                climateData[i].Location  = climateDataRaw[i].Location;
                climateData[i].Timestamp = climateDataRaw[i].Timestamp.Replace("Today", "I dag");
            }
            ViewData["ClimateData"]     = climateData;
            ViewData["AlarmStatusDate"] = alarmData.Date.Replace("Today", "I dag");
            ViewData["AlarmStatus"]     = alarmData.Status;
            ViewData["AlarmUser"]       = alarmData.Name;
            ViewData["AlarmLabel"]      = alarmData.Label;
            AlarmTime = alarmData.Date;
        }
Пример #12
0
    private void CreateClimate()
    {
        climateList.Clear();
        nextClimateList.Clear();
        ClimateData initialData = new ClimateData();

        initialData.moisture = startingMoisture;
        ClimateData clearData = new ClimateData();

        for (int i = 0; i < cellCount; i++)
        {
            climateList.Add(initialData);
            nextClimateList.Add(clearData);
        }

        for (int cycle = 0; cycle < 40; cycle++)
        {
            for (int i = 0; i < cellCount; i++)
            {
                EvolveClimate(i);
            }
            List <ClimateData> swap = climateList;
            climateList     = nextClimateList;
            nextClimateList = swap;
        }
    }
Пример #13
0
    IEnumerator <WaitForEndOfFrame> CreateRivers()
    {
        List <TriCell> riverOrigins = ListPool <TriCell> .Get();

        for (int i = 0; i < cellCount; i++)
        {
            TriCell cell = grid.GetCell(i);
            if (cell.IsUnderwater)
            {
                continue;
            }
            ClimateData data = climate[i];

            float weight =
                (float)(cell.Elevation) /
                (float)(elevationMaximum);
            //grid.labels[i].text = weight.ToString("F");
            if (weight > 0.75f)
            {
                riverOrigins.Add(cell);
                riverOrigins.Add(cell);
            }
            if (weight > 0.5f)
            {
                riverOrigins.Add(cell);
            }
            if (weight > 0.25f)
            {
                riverOrigins.Add(cell);
            }
        }
        int riverBudget     = Mathf.RoundToInt(landCells * riverPercentage * 0.01f);
        int overflowChecker = 0;

        while (riverBudget > 0 && riverOrigins.Count > 0)
        {
            if (overflowChecker++ > 1000)
            {
                Debug.Log("checking river stack overflowed");
                break;
            }
            int     index     = Random.Range(0, riverOrigins.Count);
            int     lastIndex = riverOrigins.Count - 1;
            TriCell origin    = riverOrigins[index];
            riverOrigins[index] = riverOrigins[lastIndex];
            riverOrigins.RemoveAt(lastIndex);
            if (!origin.HasRiver)
            {
                riverBudget -= CreateRiver(origin);
            }
            yield return(null);
        }

        if (riverBudget > 0)
        {
            Debug.LogWarning("Failed to use up river budget.");
        }
        ListPool <TriCell> .Add(riverOrigins);
    }
Пример #14
0
    public override void OnGUI(
        Rect position,
        SerializedProperty property,
        GUIContent label
        )
    {
        ClimateData cubeVector = new ClimateData(
            property.FindPropertyRelative("clouds").floatValue,
            property.FindPropertyRelative("moisture").floatValue,
            property.FindPropertyRelative("temperature").floatValue
            );

        position = EditorGUI.PrefixLabel(position, label);
        GUI.Label(position, cubeVector.ToString());
    }
Пример #15
0
    void EvolveClimate(int cellIndex)
    {
        TriCell     cell = grid.GetCell(cellIndex);
        ClimateData cellClimate = climate[cellIndex];
        float       tMoisture = cellClimate.moisture, tClouds = cellClimate.clouds;

        if (cell.IsUnderwater)
        {
            tMoisture = 1f;
            tClouds  += evaporationFactor;
        }
        else
        {
            float evaporation = tMoisture * evaporationFactor;
            tMoisture -= evaporation;
            tClouds   += evaporation;
        }
        float precipitation = tClouds * precipitationFactor;

        tClouds   -= precipitation;
        tMoisture += precipitation;
        //SetClimateData(cellIndex, tMoisture, tClouds);
        float cloudDispersal = tClouds * (1f / 6f);
        float runoff         = tMoisture * runoffFactor * (1f / 6f);

        for (int i = 0; i < 4; i++)
        {
            TriCell neighbor = grid.GetCell(TriMetrics.TriToHex(cell.coordinates) + new Vector2Int(TriMetrics.hexDir[i, 0], TriMetrics.hexDir[i, 1]));
            if (!neighbor)
            {
                continue;
            }
            ClimateData neighborClimate = climate[neighbor.Index];
            float       tNMoisture = neighborClimate.moisture, tNClouds = neighborClimate.clouds;
            tNClouds += cloudDispersal;
            int elevationDelta = neighbor.Elevation - cell.Elevation;
            if (elevationDelta < 0)
            {
                tMoisture  -= runoff;
                tNMoisture += runoff;
            }
            SetClimateData(neighbor.Index, tNMoisture, tNClouds);
            //climate[neighbor.Index] = neighborClimate;
        }
        tClouds = 0f;
        SetClimateData(cellIndex, tMoisture, tClouds);
        //climate[cellIndex] = cellClimate;
    }
Пример #16
0
        private void SendMessageToIotHub()
        {
            var climateData = new ClimateData
            {
                DeviceId    = _hubDeviceId,
                MessageId   = 42,
                DateTime    = DateTime.UtcNow.ToLongTimeString(),
                Humidity    = new Random().Next(55, 70),
                Temperature = new Random().Next(19, 29)
            };

            var climateDataJson = JsonConvert.SerializeObject(climateData);
            var rawClimateData  = Encoding.UTF8.GetBytes(climateDataJson);
            var message         = new Microsoft.Azure.Devices.Client.Message(rawClimateData);

            _client.SendEventAsync(message);
        }
Пример #17
0
    public HexMapRivers(
        HexMap hexMap,
        List <ClimateData> climate,
        int waterLevel,
        int elevationMax
        )
    {
        _hexMap                = hexMap;
        _riverLists            = new List <RiverList>();
        _riverOriginCandidates = new List <Hex>();
        _riverDigraph          = new RiverDigraph();
        _adjacencyGraph        = hexMap.AdjacencyGraph;

        for (int i = 0; i < _hexMap.SizeSquared; i++)
        {
            Hex hex = _hexMap.GetHex(i);

            if (hex.IsUnderwater)
            {
                continue;
            }

            ClimateData data = climate[i];

            float weight =
                data.moisture * (hex.elevation - waterLevel) /
                (elevationMax - waterLevel);

            if (weight > 0.75)
            {
                _riverOriginCandidates.Add(hex);
                _riverOriginCandidates.Add(hex);
            }

            if (weight > 0.5f)
            {
                _riverOriginCandidates.Add(hex);
            }

            if (weight > 0.25f)
            {
                _riverOriginCandidates.Add(hex);
            }
        }
    }
Пример #18
0
        public async Task <IActionResult> CallVerisureService([FromServices] INodeServices nodeServices)
        {
            var climateDataRaw = await nodeServices.InvokeExportAsync <ClimateDataRaw[]>(VeriSureAppFilePath, "sendClimateData");

            var alarmData = await nodeServices.InvokeExportAsync <AlarmStatus>(VeriSureAppFilePath, "sendAlarmStatus");

            ClimateData[] climateData = new ClimateData[climateDataRaw.Length];

            for (int i = 0; i < climateDataRaw.Length; i++)
            {
                climateData[i]             = new ClimateData();
                climateData[i].Temperature = float.Parse(climateDataRaw[i].Temperature.Remove(climateDataRaw[i].Temperature.IndexOf('&')));
                if (climateDataRaw[i].Humidity.Equals(string.Empty))
                {
                    climateData[i].Humidity = 0;
                }
                else
                {
                    climateData[i].Humidity = float.Parse(climateDataRaw[i].Humidity.Remove(climateDataRaw[i].Humidity.IndexOf('%')));
                }

                climateData[i].Location  = climateDataRaw[i].Location;
                climateData[i].Timestamp = climateDataRaw[i].Timestamp.Replace("Today", "I dag");
            }
            ViewData["ClimateData"]     = climateData;
            ViewData["AlarmStatusDate"] = alarmData.Date.Replace("Today", "I dag");
            ViewData["AlarmStatus"]     = alarmData.Status;
            ViewData["AlarmUser"]       = alarmData.Name;
            ViewData["AlarmLabel"]      = alarmData.Label;
            AlarmTime = alarmData.Date;
            WriteToVoiceFile(climateData, alarmData);
            StartVoiceProgram();

            if (!BeginStarted)
            {
                BeginStarted = true;
                ListenAlarmChanges listenAlarmChanges = new ListenAlarmChanges(this); //Create listening on Alarmchanges
                listenAlarmChanges.Listen();
                Begin();                                                              //begin eventhandler run only once.
            }

            return(View());
        }
Пример #19
0
    public HexMapClimate(
        HexMap hexMap,
        float startingMoisture
        )
    {
        _hexMap = hexMap;
        _temperatureJitterChannel = Random.Range(0, 4);

        ClimateArray = new ClimateData[_hexMap.SizeSquared];

        for (int i = 0; i < ClimateArray.Length; i++)
        {
            ClimateData initial = new ClimateData(
                0,
                startingMoisture,
                0
                );
        }
    }
        public IActionResult GetHistoricalData()
        {
            foreach (string key in RouteData.Values.Keys)
            {
                Console.WriteLine("\nKey = " + key);
            }
            string startKey  = RouteData.Values["startKey"] + "";
            string finishKey = RouteData.Values["finishKey"] + "";

            Console.WriteLine(startKey);
            Console.WriteLine(finishKey);
            // example for query to get all the values in a range
            // var filter = builder.And(builder.Eq("status", "A"), builder.Lt("qty", 30));


            string tempJson = JsonConvert.SerializeObject(ClimateData.Instance().dashboardModels);

            System.IO.File.WriteAllText(@"C:\Git\RemoteTemperature\app\server\TemperatureServer\Data\data.txt", tempJson);
            return(Json(ClimateData.Instance().dashboardModels));
        }
Пример #21
0
    void CreateClimate()
    {
        climate.Clear();
        ClimateData initialData = new ClimateData();

        for (int i = 0; i < cellCount; i++)
        {
            climate.Add(initialData);
        }
        for (int cycle = 0; cycle < 40; cycle++)
        {
            for (int i = 0; i < cellCount; i++)
            {
                TriCoordinates t = grid.GetCell(i).coordinates;
                if (t == TriMetrics.TriToHex(t))
                {
                    EvolveClimate(i);
                }
            }
        }
    }
Пример #22
0
    public void Step(
        ClimateParameters parameters
        )
    {
        HexAdjacencyGraph adjacencyGraph =
            _hexMap.AdjacencyGraph;

        // Initialize the next climate step.
        ClimateData[] nextClimates = new ClimateData[ClimateArray.Length];

        // Populate the next climate step.
        for (int i = 0; i < ClimateArray.Length; i++)
        {
            nextClimates[i] = new ClimateData();
        }

        // For each hex cell...
        for (int i = 0; i < _hexMap.SizeSquared; i++)
        {
            Hex            source        = _hexMap.GetHex(i);
            List <HexEdge> adjacentEdges =
                adjacencyGraph.GetOutEdgesList(source);

            // Get the next climate step for that cell.
            StepClimate(
                ClimateArray,
                ref nextClimates,
                source,
                adjacentEdges,
                parameters
                );

            source.clouds      = nextClimates[source.Index].clouds;
            source.moisture    = nextClimates[source.Index].moisture;
            source.temperature = nextClimates[source.Index].clouds;
        }

        ClimateArray = nextClimates;
    }
Пример #23
0
    IEnumerator <WaitForEndOfFrame> CreateClimate()
    {
        climate.Clear();
        ClimateData initialData = new ClimateData();

        for (int i = 0; i < cellCount; i++)
        {
            climate.Add(initialData);
        }
        for (int cycle = 0; cycle < 40; cycle++)
        {
            for (int i = 0; i < cellCount; i++)
            {
                TriCoordinates t = grid.GetCell(i).coordinates;
                if (t == TriMetrics.TriToHex(t))
                {
                    EvolveClimate(i);
                }
            }
        }
        yield return(null);
    }
Пример #24
0
        public async Task <ActionResult> UpdateCurrentStatus([FromBody] ClimateModel dashModel)
        {
            if (dashModel != null)
            {
                // creates the id
                dashModel.populateFields();

                // insert into the database
                var before = await this._climateService.Create(dashModel);

                Console.WriteLine("\nBefore:" + before.temperature);

                // test that the data is in the database
                var results = _climateService.Get(dashModel.key);
                Console.WriteLine("After " + results.temperature);

                ClimateData.UpdateDashboard(dashModel);
                Console.WriteLine(ClimateData.Instance().currentClimateModel.temperature);
                //_hub.Clients.All.SendAsync("transfertemperaturedata",dashModel);
                return(Json(new ResponseModel(ResponseModel.Responses.Success)));
            }
            return(Json(new ResponseModel(ResponseModel.Responses.Error)));
        }
Пример #25
0
    private void CreateRivers()
    {
        List <HexCell> riverOrigins = ListPool <HexCell> .Get();

        for (int i = 0; i < cellCount; i++)
        {
            HexCell cell = hexGrid.GetCell(i);
            if (cell.IsUnderWater)
            {
                continue;
            }

            ClimateData data   = climateList[i];
            float       weight = data.moisture * (cell.Elevation - waterLevel) / (elevationMaxmum - waterLevel);
            if (weight > 0.75f)
            {
                riverOrigins.Add(cell);
                riverOrigins.Add(cell);
            }
            else if (weight > 0.5f)
            {
                riverOrigins.Add(cell);
            }
            else if (weight > 0.25f)
            {
                riverOrigins.Add(cell);
            }
        }

        int riverBudget = Mathf.RoundToInt(landCells * riverPercentage * 0.01f);

        while (riverBudget > 0 && riverOrigins.Count > 0)
        {
            int     index     = Random.Range(0, riverOrigins.Count);
            int     lastIndex = riverOrigins.Count - 1;
            HexCell origin    = riverOrigins[index];
            riverOrigins[index] = riverOrigins[lastIndex];
            riverOrigins.RemoveAt(lastIndex);

            if (!origin.HasRiver)
            {
                bool isValidOrigin = true;
                for (HexDirectionEnum d = 0; d < HexDirectionEnum.Length; d++)
                {
                    HexCell neighbor = origin.GetNeighbor(d);
                    if (neighbor && (neighbor.HasRiver || neighbor.IsUnderWater))
                    {
                        isValidOrigin = false;
                        break;
                    }
                }
                if (isValidOrigin)
                {
                    riverBudget -= CreateRiver(origin);
                }
            }
        }

        if (riverBudget > 0)
        {
            Debug.LogWarning("Failed to use up river budget");
        }

        ListPool <HexCell> .Add(riverOrigins);
    }
Пример #26
0
    private void EvolveClimate(int cellIndex)
    {
        HexCell     cell        = hexGrid.GetCell(cellIndex);
        ClimateData cellClimate = climateList[cellIndex];

        if (cell.IsUnderWater)
        {
            cellClimate.moisture = 1f;
            cellClimate.clouds  += evaporationFactor;
        }
        else
        {
            float evaporation = cellClimate.moisture * evaporationFactor;
            cellClimate.moisture -= evaporation;
            cellClimate.clouds   += evaporation;
        }

        float precipitation = cellClimate.clouds * precipitationFactor;

        cellClimate.moisture += precipitation;
        cellClimate.clouds   -= precipitation;

        float cloudMaximum = 1f - cell.ViewElevation / (elevationMaxmum + 1f);

        if (cellClimate.clouds > cloudMaximum)
        {
            cellClimate.moisture += cellClimate.clouds - cloudMaximum;
            cellClimate.clouds    = cloudMaximum;
        }

        HexDirectionEnum mainDispersaDirection = windDirection.Opposite();
        float            cloudDispersal        = cellClimate.clouds * (1 / (5f + windStrength));
        float            runoff  = cellClimate.moisture * runoffFactor * (1 / 6f);
        float            seepage = cellClimate.moisture * seepageFactor * (1 / 6f);

        for (HexDirectionEnum d = 0; d < HexDirectionEnum.Length; d++)
        {
            HexCell neighbor = cell.GetNeighbor(d);
            if (!neighbor)
            {
                continue;
            }

            ClimateData neighborClimate = nextClimateList[neighbor.Index];
            if (d == mainDispersaDirection)
            {
                neighborClimate.clouds += cloudDispersal * windStrength;
            }
            else
            {
                neighborClimate.clouds += cloudDispersal;
            }

            int elevationDelta = neighbor.ViewElevation - cell.ViewElevation;
            if (elevationDelta < 0)
            {
                cellClimate.moisture     -= runoff;
                neighborClimate.moisture += runoff;
            }
            else if (elevationDelta == 0)
            {
                cellClimate.moisture     -= seepage;
                neighborClimate.moisture += seepage;
            }
            nextClimateList[neighbor.Index] = neighborClimate;
        }

        ClimateData nextCellClimate = nextClimateList[cellIndex];

        nextCellClimate.moisture  += cellClimate.moisture;
        nextClimateList[cellIndex] = nextCellClimate;
        if (nextCellClimate.moisture > 1f)
        {
            nextCellClimate.moisture = 1f;
        }
        climateList[cellIndex] = new ClimateData();
    }
Пример #27
0
    /// <summary>
    /// 单个格子气候
    /// </summary>
    /// <param name="cellIndex"></param>
    void EvolveClimate(int cellIndex)
    {
        HexCell     cell        = grid.GetCell(cellIndex);
        ClimateData cellClimate = climate[cellIndex];

        // 蒸发阶段
        if (cell.IsUnderwater)                                                          // 水下
        {
            cellClimate.moisture = 1f;                                                  // 水下格子,湿度设为1
            cellClimate.clouds  += evaporationFactor;                                   // 增加云量
        }
        else                                                                            // 陆地
        {
            float evaporation = cellClimate.moisture * evaporationFactor;               // 格子湿度*单周期蒸发量 得到当前格子蒸发量
            cellClimate.clouds   += evaporation;                                        // 蒸发量转化成云量
            cellClimate.moisture -= evaporation;                                        // 由于蒸发了,所以湿度也下降了
        }


        // 降雨阶段
        float precipitation = cellClimate.clouds * precipitationFactor;                 // 降雨量

        cellClimate.clouds   -= precipitation;                                          // 去掉由于降雨消耗掉的云
        cellClimate.moisture += precipitation;                                          // 由于降水,所以湿度增加

        float cloudMaximum = 1f - cell.ViewElevation / (elevationMaximum + 1f);         // 当前海拔可容纳的最大云量(海拔越高云量越低)

        if (cellClimate.clouds > cloudMaximum)                                          // 如果当前云量超过了云最大容纳量,则强迫降雨(雨影效应)
        {
            cellClimate.moisture += cellClimate.clouds - cloudMaximum;
            cellClimate.clouds    = cloudMaximum;
        }


        // 扩散阶段
        HexDirection mainDispersalDirection = windDirection.Opposite();
        float        cloudDispersal         = cellClimate.clouds * (1f / (5f + windStrength)); // 云扩散量
        float        runoff  = cellClimate.moisture * runoffFactor * (1f / 6f);                // 河流流走的水分
        float        seepage = cellClimate.moisture * seepageFactor * (1f / 6f);               // 通过泥土渗透流失的水分

        for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)                      // 把自身的云均匀的扩散到邻居
        {
            HexCell neighbor = cell.GetNeighbor(d);
            if (!neighbor)
            {
                continue;
            }
            ClimateData neighborClimate = nextClimate[neighbor.Index];
            // 云的扩散
            if (d == mainDispersalDirection)                                            // 判断是否顺风
            {
                neighborClimate.clouds += cloudDispersal * windStrength;
            }
            else
            {
                neighborClimate.clouds += cloudDispersal;
            }

            // 水分(湿度)的扩散
            int elevationDelta = neighbor.ViewElevation - cell.ViewElevation;
            if (elevationDelta < 0)                                                     // 判断邻居是否比自己矮
            {
                cellClimate.moisture     -= runoff;                                     // 自身湿度减少(河流)
                neighborClimate.moisture += runoff;                                     // 邻居湿度增加(河流)
            }
            else if (elevationDelta == 0)                                               // 判断是否与自己有相同高度
            {
                cellClimate.moisture     -= seepage;                                    // 自身湿度减少(渗透)
                neighborClimate.moisture += seepage;                                    // 邻居湿度增加(渗透)
            }

            nextClimate[neighbor.Index] = neighborClimate;
        }
        // 扩散之后把自身云量设为0
        //cellClimate.clouds = 0f;

        // 把当前格子的数据存到下一周期数据中,其中因为云在扩散后是0,所以不用叠加到下一个周期
        ClimateData nextCellClimate = nextClimate[cellIndex];

        nextCellClimate.moisture += cellClimate.moisture;                               // 叠加湿度
        if (nextCellClimate.moisture > 1f)
        {
            nextCellClimate.moisture = 1f;
        }
        nextClimate[cellIndex] = nextCellClimate;
        climate[cellIndex]     = new ClimateData();
    }
Пример #28
0
    private void StepClimate(
        ClimateData[] currentClimates,
        ref ClimateData[] nextClimates,
        Hex source,
        List <HexEdge> adjacentEdges,
        ClimateParameters parameters
        )
    {
        ClimateData currentClimate = currentClimates[source.Index];

        // If the tile is water, add clouds equivalent to the evaporation
        // factor.
        if (source.IsUnderwater)
        {
            currentClimate.moisture = 1f;
            currentClimate.clouds  += parameters.evaporationFactor;
        }
        // If the tile is not water, scale evaporation with the moisture
        // of the tile and create clouds from that.
        else
        {
            float evaporation =
                currentClimate.moisture * parameters.evaporationFactor;

            currentClimate.moisture -= evaporation;
            currentClimate.clouds   += evaporation;
        }

        // Precipitation is scaled with the number of clouds.
        float precipitation =
            currentClimate.clouds * parameters.precipitationFactor;

        currentClimate.clouds   -= precipitation;
        currentClimate.moisture += precipitation;

        // As the elevation of the hex approaches the maximum elevation,
        // the maximum number of clouds decreases.
        float cloudMaximum =
            1f - source.ViewElevation / (parameters.elevationMax + 1f);

        // If the number of clouds exceeds the cloud maximum, convert
        // excess clouds to moisture.
        if (currentClimate.clouds > cloudMaximum)
        {
            currentClimate.moisture +=
                currentClimate.clouds - cloudMaximum;
            currentClimate.clouds = cloudMaximum;
        }

        // Get the main cloud dispersal direction.
        HexDirections mainCloudDispersalDirection =
            parameters.windDirection.Opposite();

        // Get the cloud dispersal magnitude.
        float cloudDispersalMagnitude =
            currentClimate.clouds * (1f / (5f + parameters.windStrength));

        // Calculate the amount of runoff.
        float runoff =
            currentClimate.moisture * parameters.runoffFactor * (1f / 6f);

        // Calculate the amount of seepage.
        float seepage =
            currentClimate.moisture * parameters.seepageFactor * (1f / 6f);

        // Disperse clouds, runoff, and seepage to adjacent climates.
        foreach (HexEdge edge in adjacentEdges)
        {
            ClimateData neighborClimate = nextClimates[edge.Target.Index];

            if (edge.Direction == mainCloudDispersalDirection)
            {
                neighborClimate.clouds +=
                    cloudDispersalMagnitude * parameters.windStrength;
            }
            else
            {
                neighborClimate.clouds += cloudDispersalMagnitude;
            }

            int elevationDelta =
                edge.Target.ViewElevation - edge.Source.ViewElevation;

            if (elevationDelta < 0)
            {
                currentClimate.moisture  -= runoff;
                neighborClimate.moisture += runoff;
            }
            else if (elevationDelta == 0)
            {
                currentClimate.moisture  -= seepage;
                neighborClimate.moisture += seepage;
            }

            neighborClimate.moisture =
                Mathf.Clamp(
                    neighborClimate.moisture,
                    0f,
                    1f
                    );

            nextClimates[edge.Target.Index] = neighborClimate;
        }

        ClimateData nextHexClimate = nextClimates[source.Index];

        nextHexClimate.moisture += currentClimate.moisture;

        // Ensure that no hex can have more moisture than a hex that is
        // underwater.
        nextHexClimate.moisture =
            Mathf.Clamp(
                nextHexClimate.moisture,
                0f,
                1f
                );

        nextHexClimate.temperature =
            GenerateTemperature(
                source,
                parameters.hemisphere,
                parameters.waterLevel,
                parameters.elevationMax,
                _temperatureJitterChannel,
                parameters.temperatureJitter,
                parameters.lowTemperature,
                parameters.highTemperature,
                parameters.hexOuterRadius
                );

        //Store the data for the next climate.
        nextClimates[source.Index] = nextHexClimate;
    }
Пример #29
0
    /// <summary>
    /// 生成河流
    /// </summary>
    void CreateRivers()
    {
        List <HexCell> riverOrigins = ListPool <HexCell> .Get();                                                   // 河流源头列表,用于储存可作为河流源头的六边形格子

        for (int i = 0; i < cellCount; i++)
        {
            HexCell cell = grid.GetCell(i);
            if (cell.IsUnderwater)
            {
                continue;
            }
            ClimateData data   = climate[i];
            float       weight = data.moisture * (cell.Elevation - waterLevel) / (elevationMaximum - waterLevel); // 湿度(0~1)* 海拔百分比(0~1)得到权重
            if (weight > 0.75f)
            {
                // 添加两次增加选中的概率
                riverOrigins.Add(cell);
                riverOrigins.Add(cell);
            }
            if (weight > 0.5f)
            {
                riverOrigins.Add(cell);
            }
            if (weight > 0.25f)
            {
                riverOrigins.Add(cell);
            }
        }

        int riverBudget = Mathf.RoundToInt(landCells * riverPercentage * 0.01f);                                // 计算得到河流格子数目预算

        while (riverBudget > 0 && riverOrigins.Count > 0)
        {
            // 随机选出河流源头
            int     index     = Random.Range(0, riverOrigins.Count);
            int     lastIndex = riverOrigins.Count - 1;
            HexCell origin    = riverOrigins[index];

            bool isValidOrigin = true;
            // 检查附近是否有河流或者水,如果有,则不允许作为河流源头(避免河流源头集中在一起)
            for (HexDirection d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                HexCell neighbor = origin.GetNeighbor(d);
                if (neighbor && (neighbor.HasRiver || neighbor.IsUnderwater))
                {
                    isValidOrigin = false;
                    break;
                }
            }
            if (isValidOrigin)
            {
                // 创建河流
                riverBudget -= CreateRiver(origin);
            }

            // 把选出来的河流源头从列表移除
            riverOrigins[index] = riverOrigins[lastIndex];
            riverOrigins.RemoveAt(lastIndex);
        }

        if (riverBudget > 0)
        {
            Debug.LogWarning("河流预算没有用完。");
        }

        ListPool <HexCell> .Add(riverOrigins);
    }
        private void EvolveClimate(int cellIndex)
        {
            var cell        = Grid.GetCell(cellIndex);
            var cellClimate = climate[cellIndex];

            if (cell.IsUnderwater)
            {
                cellClimate.Moisture = 1f;
                cellClimate.Clouds  += Evaporation;
            }
            else
            {
                var evaporation = cellClimate.Moisture * EvaporationFactor;
                cellClimate.Moisture -= evaporation;
                cellClimate.Clouds   += evaporation;
            }

            var precipitation = cellClimate.Clouds * PrecipitationFactor;

            cellClimate.Clouds   -= precipitation;
            cellClimate.Moisture += precipitation;

            var cloudMaximum = 1f - cell.ViewElevation / (ElevationMaximum + 1f);

            if (cellClimate.Clouds > cloudMaximum)
            {
                cellClimate.Moisture += cellClimate.Clouds - cloudMaximum;
                cellClimate.Clouds    = cloudMaximum;
            }

            var mainDispersalDirection = WindDirection.Opposite();
            var cloudDispersal         = cellClimate.Clouds / (5f + WindStrength);

            var runoff  = cellClimate.Moisture * RunoffFactor / 6f;
            var seepage = cellClimate.Moisture * SeepageFactor / 6f;

            for (var d = HexDirection.NE; d <= HexDirection.NW; d++)
            {
                var neighbour = cell.GetNeighbour(d);
                if (!neighbour)
                {
                    continue;
                }

                var neighbourClimate = nextClimate[neighbour.Index];

                if (d == mainDispersalDirection)
                {
                    neighbourClimate.Clouds += cloudDispersal * WindStrength;
                }
                else
                {
                    neighbourClimate.Clouds += cloudDispersal;
                }

                var elevationDelta = neighbour.ViewElevation - cell.ViewElevation;
                if (elevationDelta < 0)
                {
                    cellClimate.Moisture      -= runoff;
                    neighbourClimate.Moisture += runoff;
                }
                else if (elevationDelta == 0)
                {
                    cellClimate.Moisture      -= seepage;
                    neighbourClimate.Moisture += seepage;
                }

                nextClimate[neighbour.Index] = neighbourClimate;
            }

            var nextCellClimate = nextClimate[cellIndex];

            nextCellClimate.Moisture += cellClimate.Moisture;
            if (nextCellClimate.Moisture > 1f)
            {
                nextCellClimate.Moisture = 1f;
            }
            nextClimate[cellIndex] = nextCellClimate;
            climate[cellIndex]     = new ClimateData();;
        }