Пример #1
0
 /// <summary>
 /// Calculates the approximate area of a point on a map projection with the given
 /// characteristics, by transforming the point and its nearest neighbors to latitude and
 /// longitude, calculating the midpoints between them, and calculating the area of the
 /// region enclosed within those midpoints.
 /// </summary>
 /// <param name="radius">The radius of the planet.</param>
 /// <param name="x">The x coordinate of a point on a map projection, with zero as the
 /// westernmost point.</param>
 /// <param name="y">The y coordinate of a point on a map projection, with zero as the
 /// northernmost point.</param>
 /// <param name="resolution">The vertical resolution of the projection.</param>
 /// <param name="options">
 /// The map projection options used to generate the map used.
 /// </param>
 /// <returns>The area of the given point, in m².</returns>
 public static HugeNumber GetAreaOfPoint(
     HugeNumber radius,
     int x, int y,
     int resolution,
     MapProjectionOptions options) => GetAreaOfPointFromRadiusSquared(
     radius.Square(),
     x, y,
     (int)Math.Floor(resolution * options.AspectRatio),
     resolution,
     options);
Пример #2
0
 /// <summary>
 /// Calculates the approximate area of a point on a map projection with the given
 /// characteristics, by transforming the point and its nearest neighbors to latitude and
 /// longitude, calculating the midpoints between them, and calculating the area of the
 /// region enclosed within those midpoints.
 /// </summary>
 /// <param name="region">The mapped region.</param>
 /// <param name="planet">The mapped planet.</param>
 /// <param name="x">The x coordinate of a point on a map projection, with zero as the
 /// westernmost point.</param>
 /// <param name="y">The y coordinate of a point on a map projection, with zero as the
 /// northernmost point.</param>
 /// <param name="resolution">The vertical resolution of the projection.</param>
 /// <param name="options">
 /// The map projection options used to generate the map used.
 /// </param>
 /// <returns>The area of the given point, in m².</returns>
 public static HugeNumber GetAreaOfLocalPoint(
     this SurfaceRegion region,
     Planetoid planet,
     int x, int y,
     int resolution,
     MapProjectionOptions options) => SurfaceMap.GetAreaOfPointFromRadiusSquared(
     planet.RadiusSquared,
     x, y,
     (int)Math.Floor(resolution * options.AspectRatio),
     resolution,
     region.GetProjection(planet, options.EqualArea));
Пример #3
0
    public void EarthlikePlanet()
    {
        // First run to ensure timed runs do not include any one-time initialization costs.
        _ = Planetoid.GetPlanetForSunlikeStar(out _);

        var stopwatch = new Stopwatch();

        stopwatch.Start();

        var planet = Planetoid.GetPlanetForSunlikeStar(out _);

        stopwatch.Stop();

        Assert.IsNotNull(planet);

        Console.WriteLine($"Planet generation time: {stopwatch.Elapsed:s'.'FFF} s");
        Console.WriteLine($"Radius: {planet!.Shape.ContainingRadius / 1000:N0} km");
        Console.WriteLine($"Surface area: {planet!.Shape.ContainingRadius.Square() * HugeNumberConstants.FourPi / 1000000:N0} km²");

        stopwatch.Restart();

        using (var elevationMap = planet.GetElevationMap(MapResolution))
        {
            var(winterTemperatureMap, summerTemperatureMap) = planet.GetTemperatureMaps(elevationMap, MapResolution);
            var(precipitationMaps, snowfallMaps)            = planet
                                                              .GetPrecipitationAndSnowfallMaps(winterTemperatureMap, summerTemperatureMap, MapResolution, Seasons);
            for (var i = 0; i < snowfallMaps.Length; i++)
            {
                snowfallMaps[i].Dispose();
            }
            using var precipitationMap = SurfaceMapImage.AverageImages(precipitationMaps);
            for (var i = 0; i < precipitationMaps.Length; i++)
            {
                precipitationMaps[i].Dispose();
            }
            _ = new WeatherMaps(
                planet,
                elevationMap,
                winterTemperatureMap,
                summerTemperatureMap,
                precipitationMap,
                MapResolution,
                MapProjectionOptions.Default);
            winterTemperatureMap.Dispose();
            summerTemperatureMap.Dispose();
        }

        stopwatch.Stop();

        Console.WriteLine($"Equirectangular surface map generation time: {stopwatch.Elapsed:s'.'FFF} s");

        var projection = new MapProjectionOptions(equalArea: true);

        stopwatch.Restart();

        using var elevationMapEA = planet.GetElevationMap(MapResolution, projection);
        var(winterTemperatureMapEA, summerTemperatureMapEA) = planet.GetTemperatureMaps(elevationMapEA, MapResolution, projection, projection);
        using var temperatureMapEA = SurfaceMapImage.AverageImages(winterTemperatureMapEA, summerTemperatureMapEA);
        var(precipitationMapsEA, snowfallMapsEA) = planet
                                                   .GetPrecipitationAndSnowfallMaps(winterTemperatureMapEA, summerTemperatureMapEA, MapResolution, Seasons, projection, projection);
        for (var i = 0; i < snowfallMapsEA.Length; i++)
        {
            snowfallMapsEA[i].Dispose();
        }
        using var precipitationMapEA = SurfaceMapImage.AverageImages(precipitationMapsEA);
        for (var i = 0; i < precipitationMapsEA.Length; i++)
        {
            precipitationMapsEA[i].Dispose();
        }
        var climateMapsEA = new WeatherMaps(
            planet,
            elevationMapEA,
            winterTemperatureMapEA,
            summerTemperatureMapEA,
            precipitationMapEA,
            MapResolution,
            projection);

        winterTemperatureMapEA.Dispose();
        summerTemperatureMapEA.Dispose();

        stopwatch.Stop();

        Console.WriteLine($"Cylindrical equal-area surface map generation time: {stopwatch.Elapsed:s'.'FFF} s");

        var normalizedSeaLevel = planet.SeaLevel / planet.MaxElevation;
        var elevationRange     = planet.GetElevationRange(elevationMapEA);
        var landCoords         = 0;

        if (planet.Hydrosphere?.IsEmpty == false)
        {
            for (var x = 0; x < elevationMapEA.Width; x++)
            {
                for (var y = 0; y < elevationMapEA.Height; y++)
                {
                    var value = (2.0 * elevationMapEA[x, y].PackedValue / ushort.MaxValue) - 1;
                    if (value - normalizedSeaLevel > 0)
                    {
                        landCoords++;
                    }
                }
            }
        }
        var sb = new StringBuilder();

        AddTempString(sb, temperatureMapEA);
        sb.AppendLine();
        AddTerrainString(sb, planet, elevationMapEA, landCoords);
        sb.AppendLine();
        AddClimateString(sb, elevationMapEA, normalizedSeaLevel, landCoords, climateMapsEA);
        sb.AppendLine();
        AddPrecipitationString(sb, planet, elevationMapEA, precipitationMapEA, normalizedSeaLevel, landCoords, climateMapsEA);
        Console.WriteLine(sb.ToString());
    }