Skip to content

Commit

Permalink
Merge remote-tracking branch 'effin/new-weather' into new-weather-rework
Browse files Browse the repository at this point in the history
  • Loading branch information
wito committed Jul 2, 2014
2 parents 1a5806f + d07e423 commit caaadd6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 23 deletions.
55 changes: 33 additions & 22 deletions src/weather_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
#include <sstream>
#include <fstream>

const double pi = std::acos(-1);
const double tau = pi * 2.0;
const double tau = 2 * std::acos(-1);

weather_generator::weather_generator(unsigned seed) : SEED(seed), Temperature(SEED), Humidity(SEED + 101), Pressure(SEED + 211) { }

Expand All @@ -20,36 +19,48 @@ w_point weather_generator::get_weather(double x, double y, calendar t) {
double H2(Humidity.noise(x, y, z) / 4);
double P(Pressure.noise(x, y, z / 3) * 70);

// temperature variation
const double now((double)t.turn_of_year() / (double)calendar::year_turns()); // [0,1)
const double ctn(cos(tau * now));
const double mod_t = 0; // TODO: make this depend on latitude and altitude?
const double current_t = this->base_t + mod_t; // Current baseline temperature. Degrees Celsius.
const double seasonal_variation = ctn * -1; // Start and end at -1 going up to 1 in summer.
const double season_atenuation = ctn / 2 + 1; // Harsh winter nights, hot summers.
const double season_dispersion = pow(2, ctn * -1 + 1) - 2.3; // Make summers peak faster and winters not perma-frozen.
const double daily_variation = cos( tau * dayFraction ) * season_atenuation + season_dispersion; // Day-night temperature variation.

// Temperature variation
const double mod_t(0); // TODO: make this depend on latitude and altitude?
const double current_t(this->base_t + mod_t); // Current baseline temperature. Degrees Celsius.
const double seasonal_variation(ctn * -1); // Start and end at -1 going up to 1 in summer.
const double season_atenuation(ctn / 2 + 1); // Harsh winter nights, hot summers.
const double season_dispersion(pow(2, ctn * -1 + 1) - 2.3); // Make summers peak faster and winters not perma-frozen.
double daily_variation(cos( tau * dayFraction ) * season_atenuation + season_dispersion); // Day-night temperature variation.
T += current_t; // Add baseline to the noise.

const double D(seasonal_variation * 12 * exp(-pow(current_t * 2.7 / 20 - 0.5, 2)));
T += D; // Add season curve offset to account for the winter-summer difference in day-night difference.

T += seasonal_variation * 12 * exp(-pow(current_t * 2.7 / 20 - 0.5, 2)); // Add season curve offset to account for the winter-summer difference in day-night difference.
T += daily_variation * 10 * exp(-pow(current_t / 30, 2)); //((4000 / (current_t + 115) - 24) + seasonal_variation); // Add daily variation scaled to the inverse of the current baseline. A very specific and finicky adjustment curve.

// humidity variation
const double mod_h = 0;
const double current_h = this->base_h + mod_h;
// Humidity variation
double mod_h(0);
double current_h(this->base_h + mod_h);
H = std::max(std::min((ctn / 10.0 + (-pow(H, 2)*3 + H2)) * current_h/2.0 + current_h, 100.0), 0.0); // Humidity stays mostly at the mean level, but has low peaks rarely. It's a percentage.

// pressure variation
const double mod_p = 0;
const double current_p = this->base_p + mod_p;
P += seasonal_variation * 20 + current_p; // Pressure is mostly random, but a bit higher on summer and lower on winter. In millibars.

return w_point(T, H, P);
}

weather_type weather_generator::get_weather_conditions(double x, double y, calendar t) {
w_point w(get_weather(x, y , t));
weather_type r(WEATHER_CLEAR);
if (w.pressure > 1030 && w.humidity < 70) r = WEATHER_SUNNY;
if (w.pressure < 1030 && w.humidity > 40) r = WEATHER_CLOUDY;
if (r == WEATHER_CLOUDY && (w.humidity > 60 || w.pressure < 1010)) r = WEATHER_DRIZZLE;
if (r == WEATHER_DRIZZLE && (w.humidity > 70 || w.pressure < 1000)) r = WEATHER_RAINY;
if (r == WEATHER_RAINY && w.pressure < 950) r = WEATHER_THUNDER;
if (r == WEATHER_THUNDER && w.pressure < 900) r = WEATHER_LIGHTNING;
// TODO: Acid rain needs a different layer or method of determining acidity.
if (r == WEATHER_DRIZZLE && w.temperature > 30) r = WEATHER_ACID_DRIZZLE;
if (r > WEATHER_DRIZZLE && w.temperature > 30) r = WEATHER_ACID_RAIN;
if (w.temperature <= 0) {
if (r == WEATHER_DRIZZLE) {r = WEATHER_FLURRIES;}
else if (r > WEATHER_DRIZZLE) {r = WEATHER_SNOW;}
else if (r > WEATHER_THUNDER) {r = WEATHER_SNOWSTORM;}
}
return r;
}

void weather_generator::test_weather() {
// Outputs a Cata year's worth of weather data to a csv file.
// Usage:
Expand All @@ -59,8 +70,8 @@ void weather_generator::test_weather() {
std::ostringstream ss;
testfile.open("weather.output", std::ofstream::trunc);
testfile << "turn,temperature(C),humidity(%),pressure(mB)\n";

for (calendar i(0); i.get_turn() < 14400 * calendar::year_length(); i+=200) {
// for (calendar i(0); i.get_turn() < 1000; i.increment()) {
ss.str("");
w_point w = get_weather(0.5,0.5,i);
ss << i.get_turn() << "," << w.temperature << "," << w.humidity << "," << w.pressure;
Expand Down
3 changes: 2 additions & 1 deletion src/weather_gen.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _WEATHER_GEN_H_
#define _WEATHER_GEN_H_

#include "weather.h"
#include "calendar.h"
#include "PerlinNoise.hpp"

Expand All @@ -20,7 +21,6 @@ class PerlinNoise;

class weather_generator
{
//friend class calendar;
unsigned SEED;
// Data source: Wolfram Alpha
const double base_t = 6.5; // Average temperature of New England
Expand All @@ -32,6 +32,7 @@ class weather_generator
public:
weather_generator(unsigned seed);
w_point get_weather(double x, double y, calendar t);
weather_type get_weather_conditions(double x, double y, calendar t);
void test_weather();
};
#endif

0 comments on commit caaadd6

Please sign in to comment.