/// <summary> /// Generates a new set of precipitation and snowfall map images. /// </summary> /// <param name="planet">The planet being mapped.</param> /// <param name="winterTemperatures">A winter temperature map.</param> /// <param name="summerTemperatues">A summer temperature map.</param> /// <param name="resolution">The vertical resolution.</param> /// <param name="steps"> /// The number of maps to generate internally (representing evenly spaced "seasons" during a year, /// starting and ending at the winter solstice in the northern hemisphere). /// </param> /// <param name="temperatureProjection"> /// <para> /// The map projection of the temperature maps. They must be the same. /// </para> /// <para> /// If left <see langword="null"/> an equirectangular projection of the full globe is /// assumed. /// </para> /// </param> /// <param name="projection"> /// <para> /// The map projection options used. /// </para> /// <para> /// If left <see langword="null"/> an equirectangular projection of the full globe is /// produced. /// </para> /// </param> /// <returns> /// A set of precipitation and snowfall map images. Pixel luminosity indicates /// precipitation in mm/hr, relative to the <see cref="Atmosphere.MaxPrecipitation"/> of /// this planet's <see cref="Atmosphere"/>. /// </returns> public static (Image <L16>[] precipitationMaps, Image <L16>[] snowfallMaps) GetPrecipitationAndSnowfallMaps( this Planetoid planet, Image <L16> winterTemperatures, Image <L16> summerTemperatues, int resolution, int steps, MapProjectionOptions?temperatureProjection = null, MapProjectionOptions?projection = null) { var options = projection ?? MapProjectionOptions.Default; var precipitationMaps = new Image <L16> [steps]; var snowMaps = new Image <L16> [steps]; if (planet.Atmosphere.MaxPrecipitation.IsNearlyZero()) { var xResolution = (int)Math.Floor(resolution * options.AspectRatio); for (var i = 0; i < steps; i++) { precipitationMaps[i] = new Image <L16>(xResolution, resolution); snowMaps[i] = new Image <L16>(xResolution, resolution); } return(precipitationMaps, snowMaps); } var noise1 = new FastNoise(planet.Seed4, 1.0, FastNoise.NoiseType.Simplex); var noise2 = new FastNoise(planet.Seed5, 3.0, FastNoise.NoiseType.SimplexFractal, octaves: 3); var proportionOfYear = 1f / steps; var proportionOfYearAtMidpoint = 0f; var trueAnomaly = planet.WinterSolsticeTrueAnomaly; var trueAnomalyPerSeason = DoubleConstants.TwoPi / steps; for (var i = 0; i < steps; i++) { var solarDeclination = planet.GetSolarDeclination(trueAnomaly); (precipitationMaps[i], snowMaps[i]) = SurfaceMapImage.GenerateMapImages( new[] { winterTemperatures, summerTemperatues }, (lat, lon, temperature) => { var precipitation = planet.GetPrecipitationNoise( noise1, noise2, planet.LatitudeAndLongitudeToDoubleVector(lat, lon), lat, Planetoid.GetSeasonalLatitudeFromDeclination(lat, solarDeclination), temperature * SurfaceMapImage.TemperatureScaleFactor, out var snow); return( precipitation / planet.Atmosphere.MaxPrecipitation, snow / planet.Atmosphere.MaxSnowfall); },
/// <summary> /// Generates an elevation map image for this planet. /// </summary> /// <param name="planet">The mapped planet.</param> /// <param name="resolution">The vertical resolution of the map.</param> /// <param name="options"> /// <para> /// The map projection options used. /// </para> /// <para> /// If left <see langword="null"/> an equirectangular projection of the full globe is /// produced. /// </para> /// </param> /// <returns>An elevation map image for this planet.</returns> public static Image <L16> GetElevationMap( this Planetoid planet, int resolution, MapProjectionOptions?options = null) { if (planet.MaxElevation.IsNearlyZero()) { return(SurfaceMapImage.GenerateZeroMapImage(resolution, options, true)); } var noise1 = new FastNoise(planet.Seed1, 0.8, FastNoise.NoiseType.SimplexFractal, octaves: 6); var noise2 = new FastNoise(planet.Seed2, 0.6, FastNoise.NoiseType.SimplexFractal, FastNoise.FractalType.Billow, octaves: 6); var noise3 = new FastNoise(planet.Seed3, 1.2, FastNoise.NoiseType.Simplex); return(SurfaceMapImage.GenerateMapImage( (lat, lon) => GetElevationNoise(noise1, noise2, noise3, planet.LatitudeAndLongitudeToDoubleVector(lat, lon)), resolution, options, true)); }