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; } }
/// <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; } }
public ActionResult GetCurrentStatus() { // TemperatureData.Instance().currentDashModel = new DashboardModel(5, 6, "June 28, 2019", "9:54"); ClimateModel dm = ClimateData.Instance().currentClimateModel; return(Json(dm)); }
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(); } } }
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; } }
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; } }
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; } }
// 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]; }
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; }
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; } }
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); }
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()); }
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; }
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); }
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); } } }
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()); }
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)); }
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); } } } }
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; }
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); }
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))); }
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); }
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(); }
/// <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(); }
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; }
/// <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();; }