public TerrainPoint GetTerrainAt(GameCoordinate coordinates)
        {
            var altitude = GetAltitude(this.altitude.GetValue(coordinates));
            var heat     = GetHeat(this.heat.GetValue(coordinates), altitude);
            var humidity = GetHumidity(this.humidity.GetValue(coordinates), heat);

            return(new TerrainPoint(
                       coordinates,
                       humidity,
                       heat,
                       altitude,
                       (FeatureBlend(feature, coordinates) / sumFractalRange).Clamp(-1, 1)
                       ));
        }
        private float FeatureBlend(IModule2D feature, GameCoordinate coordinates)
        {
            const float multFactor = 6000;
            const float stepSize   = 100;
            // guarantees coords as 0 <= coord < stepSize
            var onex       = ((coordinates.x % stepSize) + stepSize) % stepSize;
            var oney       = ((coordinates.y % stepSize) + stepSize) % stepSize;
            var altx       = onex + stepSize;
            var alty       = oney + stepSize;
            var xWeight    = onex / stepSize;
            var yWeight    = oney / stepSize;
            var invXWeight = 1 - xWeight;
            var invYWeight = 1 - yWeight;

            return(feature.GetValue(onex * multFactor, oney * multFactor) * xWeight * yWeight
                   + feature.GetValue(altx * multFactor, oney * multFactor) * invXWeight * yWeight
                   + feature.GetValue(onex * multFactor, alty * multFactor) * xWeight * invYWeight
                   + feature.GetValue(altx * multFactor, alty * multFactor) * invXWeight * invYWeight);
        }
        public TerrainPoint(GameCoordinate coordinates, float humidity, float heat, float altitude, float feature)
        {
            this.coordinates = coordinates;
            this.humidity    = humidity;
            this.heat        = heat;
            this.altitude    = altitude;
            this.feature     = feature;


            temperatureCategory = (TemperatureCategory)tempsStep.FindIndex(t => t > heat);
            humidityCategory    = (HumidityCategory)Math.Min(
                BiomeDetails.biomeLabels[temperatureCategory].Count - 1,
                Math.Floor((int)HumidityCategory.Superhumid * (this.humidity / 2 + 0.5f))
                );
            altitudeCategory = (AltitudeCategory)altitudeStep.FindIndex(t => t > altitude);
            //System.Diagnostics.Debug.Assert(temperatureCategory >= TemperatureCategory.Polar && temperatureCategory <= TemperatureCategory.Tropical);
            //System.Diagnostics.Debug.Assert(humidityCategory >= HumidityCategory.Superarid && humidityCategory <= HumidityCategory.Superhumid);
            //System.Diagnostics.Debug.Assert(altitudeCategory >= AltitudeCategory.DeepWater && altitudeCategory <= AltitudeCategory.Mountain);
        }
 public static float GetValue(this IModule2D module, GameCoordinate coordinates) => module.GetValue(coordinates.x, coordinates.y);