Jump to content

I have created Wind ... any thoughts on simulated weather systems in KSP?


DoctorDavinci

Recommended Posts

So I've created a mod or two in my time and after being asked numerous times to  fully release my creations, I decided to open up my bag of tricks and start putting something together

I have cracked Geo Caching, a rudimentary challenge creator as well as Scuba Diving and Wind (among others :wink:) and now I am in the process of working out some form of a weather simulation to control the wind direction on the fly 

Looking for input if any care to offer some

Link to comment
Share on other sites

It should be like our wind simplified, mildly varied/unpredictable not only moment to moment and minute to minute, but day to day. The general direction should be known but it can vary say from 0-200% at any given time, smoothly (no 0% one second, 200% the next, though over 5 seconds it could vary that much. Just throwing out numbers).

The general direction and amount should very slowly change on an hour scale and that should be predictable out several days with relative sureness. Maybe only after you get some weather satellites in orbit.

To simplify things it should only be horizontal around the ground and unless you want to go mad, the whole planet could have a global wind direction. Don't know how best to handle variances with latitude.

Link to comment
Share on other sites

19 minutes ago, 5thHorseman said:

It should be like our wind simplified, mildly varied/unpredictable not only moment to moment and minute to minute, but day to day.

This type of complexity may come in time since creating a mathematical model to do as you describe would involve a number of variables such as humidity, temperature and what biomes are surrounding the current one coupled with overall wind directions at latitude (just conjecture) ... however it is quite doable, in a simplified manner of course :rolleyes:

23 minutes ago, 5thHorseman said:

The general direction and amount should very slowly change on an hour scale and that should be predictable out several days with relative sureness. Maybe only after you get some weather satellites in orbit.

Wind speed and direction variability is in the code already, works pretty good too :wink: ...

Spoiler

            if (windVariability <= 1)
            {
                windVariability = 1;
            }

            if (variationIntensity <= 1)
            {
                variationIntensity = 1;
            }

            if (teaseDelay <= 1)
            {
                teaseDelay = 1;
            }

            if (windIntensity <= 1)
            {
                windIntensity = 1;
            }

            int windSpeedMod = new System.Random().Next(1, 50); // generate random wind speed modifier for adjusting intensity of wind to simulate lulls and gusts
            int random = new System.Random().Next(1, 100); // for deciding if wind speed is to increae or decrease using the wind speed modifier

            // The below if statement allows for wind intensity changes over time within + or - 10% of the wind intensity setting
            if (random >= 50) // if random is above 50
            {
                //Debug.Log("[Wind} ... Changing wind speed");
                _wi = (windIntensity + (windSpeedMod / 50)) / 10; // increase wind speed by adding the wind speed modifier divided by 50 to wind speed
            }
            else // if random is below 51
            {
                //Debug.Log("[Wind} ... Changing wind speed");
                _wi = (windIntensity - (windSpeedMod / 50)) / 10;// decrese wind speed by subtracting the wind speed modifier divided by 50 to wind speed
            }

 

            int randomDirection = new System.Random().Next(1, 10); // randomizer for variable wind direction ... for determining if wind direction should change and in which direction
            int randomYaw = new System.Random().Next(1, 100); // amount of wind direction change, if any

            // the following code determines any wind direction changes over time
            if (randomDirection <= 6) // if random direction is below 6
            {
                if (randomDirection >= 2) // if random direction is above 2
                {
                    float angle = Vector3.Angle(windDirection, originalWindDirection);

                    if (angle <= windVariability / 100)
                    {
                        Debug.Log("[Wind} ... Changing direction");
                        if (!random360)
                        {
                            windDirection = Quaternion.Euler(0, -randomYaw / (variationIntensity * 10), 0) * windDirection; // Change direction by subtracting the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                        else
                        {
                            windDirection = Quaternion.Euler(0, -randomYaw / (variationIntensity * 10), 0) * GeneralWindDirection; // Change direction by subtracting the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                    }
                    else
                    {
                        if (!random360)
                        {
                            variationCount += 1;
                            Debug.Log("[Wind} ... Changing direction");
                            windDirection = Quaternion.Euler(0, randomYaw / (variationIntensity * 10), 0) * windDirection; // Change direction by adding the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                        else
                        {
                            variationCount += 1;
                            Debug.Log("[Wind} ... Changing direction");
                            windDirection = Quaternion.Euler(0, randomYaw / (variationIntensity * 10), 0) * GeneralWindDirection; // Change direction by adding the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                    }

                    if (variationCount >= 3) // && random360)
                    {
                        originalWindDirection = windDirection;
                        variationCount = 0;
                    }
                }
            }
            else// if random direction is above 5
            {
                if (randomDirection <= 9) // if random direction is below 9
                {
                    float angle = Vector3.Angle(windDirection, originalWindDirection);

                    if (angle <= windVariability / 100)
                    {
                        Debug.Log("[Wind} ... Changing direction");
                        if (!random360)
                        {
                            windDirection = Quaternion.Euler(0, randomYaw / (variationIntensity * 10), 0) * windDirection; // Change direction by subtracting the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                        else
                        {
                            windDirection = Quaternion.Euler(0, randomYaw / (variationIntensity * 10), 0) * GeneralWindDirection; // Change direction by adding the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                    }
                    else
                    {
                        variationCount += 1;
                        Debug.Log("[Wind} ... Changing direction");
                        if (!random360)
                        {
                            windDirection = Quaternion.Euler(0, -randomYaw / (variationIntensity * 10), 0) * windDirection; // Change direction by subtracting the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                        else
                        {
                            windDirection = Quaternion.Euler(0, -randomYaw / (variationIntensity * 10), 0) * GeneralWindDirection; // Change direction by adding the randomized yaw divided by 1000 from the wind direction Y vector
                        }
                    }

                    if (variationCount >= 3) // && random360)
                    {
                        originalWindDirection = windDirection;
                        variationCount = 0;
                    }
                }
            }

            StartCoroutine(Tease());

 

As for predictability, that is possible in the future as I do intend to create virtual 'sprites' in the code  to represent storm systems but that will come after the foundation I am creating is ready for it

The weather sat idea is pretty cool ... I actually created wind so @SpannerMonkey(smce) could go sailing with his pirate ships in KSP so I hadn't even thought about it (I even have cannon and cannon ball code for it :cool:)

29 minutes ago, 5thHorseman said:

o simplify things it should only be horizontal around the ground and unless you want to go mad, the whole planet could have a global wind direction. Don't know how best to handle variances with latitude.

I'm handling the wind through a tiered top down system ... the MesoSphere represents the control direction calculated off of the latitude and longitude of the active vessel and the TropoSphere wind direction is either a north westerly, south westerly, north trade wind or south trade wind (based off of a basic interpretation of atmospheric flow on earth) calculated off of the latitude of the active vessel (unless within 3 degrees of a pole which then the wind direction is due east)

At the moment the end product wind direction is either the sum or the difference of those vectors ran against a virtual vector that is created through some more math trickery (basically a virtual point in space that varies depending on latitude and longitude to the effect of rotating the virtual vector) ... I intend to add in some more modifiers to simulate the effect of ground elevation on the vector of the wind to simulate updrafts and such (Hang Gliding comes to mind :cool:)

Anyways, here's some of the code I just described above for the weather system (360random = true) ... the whole kit and kaboodle so far is sitting at a little over 15 000 lines of code although the wind part is less than 1000 (the geocaching alone took 10 000 or so)

Thoughts?

Spoiler

                teaseDelay = windSpeedMod;

                // using the north vector we can establish the general direction of the trade winds and westerlies
                NorthWesterlies = ((NorthVect - EastVect).normalized - EastVect).normalized;
                SouthWesterlies = ((-NorthVect - EastVect).normalized - EastVect).normalized;
                NorthTrades = ((NorthVect - (-EastVect)).normalized - (-EastVect)).normalized;
                SouthTrades = ((-NorthVect - (-EastVect)).normalized - (-EastVect)).normalized;

                // get the current vessels position ... create clean new vector
                currentPos = new Vector3d(FlightGlobals.ActiveVessel.latitude,
                    FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.altitude);

                // declare a virtual position to rotate around the active vessel based off of coords
                Vector3d virtualPos = new Vector3d();

                // get how many degrees in latitude difference active vessel is in relation to equator
                // 0.0055555556f is approx 1 degree
                degOffset = FlightGlobals.ActiveVessel.latitude / 0.0055555556f;

                if (currentPos.x >= 0) // if in the northern hemisphere
                {
                    if (currentPos.x <= 0.6)
                    {
                        TropoSphere = NorthWesterlies;
                    }
                    else
                    {
                        TropoSphere = NorthTrades;
                    }

                    if (currentPos.x <= 1 - (0.0055555556f * 3)) // if more than 3 degree from the north pole
                    {
                        if (currentPos.y >= 0) // if in eastern quadrant
                        {
                            if (currentPos.y <= 1 - (0.0055555556f / 2)) // if not more than half a degree from the eastern most point in coords
                            {
                                virtualPos = new Vector3d(FlightGlobals.ActiveVessel.latitude + 0.01111111111,
                   FlightGlobals.ActiveVessel.longitude + 0.02222222222 - (0.0002469136 * degOffset),
                   FlightGlobals.ActiveVessel.altitude);

                            }
                        }
                        else
                        {
                            if (currentPos.y >= -1 + (0.0055555556f / 2)) // if more than half a degree from the western most point in coords
                            {
                                virtualPos = new Vector3d(FlightGlobals.ActiveVessel.latitude + 0.01111111111,
                   FlightGlobals.ActiveVessel.longitude - 0.02222222222 + (0.0002469136 * degOffset),
                   FlightGlobals.ActiveVessel.altitude);

                            }
                        }

                        MesoSphere = (virtualPos - currentPos).normalized;
                    }
                    else
                    {
                        // MesoSphere wind direction should be east while less than 3 degrees from the poles
                        MesoSphere = EastVect;
                    }
                }
                else // if in southern hemisphere
                {
                    if (currentPos.x >= -0.6)
                    {
                        TropoSphere = SouthWesterlies;
                    }
                    else
                    {
                        TropoSphere = SouthTrades;
                    }

                    if (currentPos.x >= -1 + (0.0055555556f * 3)) // if more than 3 degree from the south pole
                    {
                        if (currentPos.y >= 0) // if in eastern quadrant
                        {
                            if (currentPos.y <= 1 - (0.0055555556f / 2)) // if not more than half a degree from the eastern most point in coords
                            {
                                virtualPos = new Vector3d(FlightGlobals.ActiveVessel.latitude - 0.01111111111,
                   FlightGlobals.ActiveVessel.longitude + 0.02222222222 - (0.0002469136 * degOffset),
                   FlightGlobals.ActiveVessel.altitude);

                            }
                        }
                        else
                        {
                            if (currentPos.y >= -1 + (0.0055555556f / 2)) // if more than half a degree from the western most point in coords
                            {
                                virtualPos = new Vector3d(FlightGlobals.ActiveVessel.latitude - 0.01111111111,
                   FlightGlobals.ActiveVessel.longitude - 0.02222222222 + (0.0002469136 * degOffset),
                   FlightGlobals.ActiveVessel.altitude);

                            }
                        }
                        MesoSphere = (virtualPos - currentPos).normalized;

                    }
                    else
                    {
                        // MesoSphere wind direction should be east while less than 3 degrees from the poles
                        MesoSphere = EastVect;
                    }
                }

                GeneralWindDirection = (TropoSphere - MesoSphere).normalized;
                windDirection = GeneralWindDirection;
            }

 

 

Link to comment
Share on other sites

1 hour ago, Drew Kerman said:

If you don't know, there was a rather extended attempt at weather earlier:

 

All rights reserved license and it the mod has been abandoned

Nobody can do anything with it

EDIT: I guess a heavy emphasis on the 'there was' part of your reply lol .... Wind and Weather is only a part of the bigger picture which is to bring more exploration options to KSP through a rebuilt OrX

Edited by DoctorDavinci
Link to comment
Share on other sites

4 hours ago, Drew Kerman said:

mainly giving you additional reference in terms of lengthy past discussion on the topic, other than code you can still look at if not directly use

Not much of a reference if the code is under an ARR license plus I am quite capable of writing my own code 

The idea behind this thread is not to copy what others have done in the past but instead to create something new

I appreciate you bringing that mod to my attention, however it is of no use to me for various reasons not to mention it was the victim of feature creep (I've been around since before 0.90 :wink:)  let alone it didn't quite work as advertised all of the time

EDIT: For reference please see the linked comment below from @Snarkwhich demonstrates exactly why the mod you mention is of no use whatsoever

 

Edited by DoctorDavinci
Link to comment
Share on other sites

Whirls.

As air masses like to move like huge whirls, maybe randomly create several 100..200 km (for Kerbin) wide whirls and calculate local wind speed and direction as their net speed.

Say, randomly generate several points (lat-long) as whirl centers, scattered across the planet surface. Invisible, just math coordinate points.

Let these whirl centers move along the planet along simple circles with slightly random constant speed, nearly like real air masses move.
Let every circular trajectory be tilted to equator at 0..60° (to not touch the poles). In fact, just make the whirl trajectory tilted at angle when it touches some circumpolar latitude with its upper edge.
So, at any moment you have exact position of every whirl center.

Add two more fixed points at both poles to have two circumpolar whirls. Absolutely same as others, but with fixed (+/-90° lat) coordinates.

Imagine whirls around every such point. Let them be enough wide to partially intersect with edges. Not visual, just imaginary whirls.

Take some very simplified formula for the horizontal (in fact, tangential, around the whirl vertical axis) wind speed value at radius from the whirl center and altitude. Anyway nobody cares about exact values.
Let the speed be the same at same radius and height, not depending on position angle. Just like a circular line around the whirl center.
This will give you both absolute value and direction of wind at any point of this whirl. (Value from radius and altitude. Wind direction is simply tangential, defined from angle relative to the whirl center.)

Randomly vary coefficients in the whirl formula to get slightly different values of wind speed in various whirls, from very weak whirls to hurricanes.

Calculate horizontal wind speed at any point as a vector sum of wind speeds calculated for whirls touching this point at this altitude.

Now you have local horizontal wind speed at any point of the planet surface by keeping in memory just 10 points and, say, 10x2 random coefficients.

***

Keep wind speed nearly zero at the whirl center to have an eye of hurricane.

***

Take very simplified basic formula of temperature (altitude).
As warm air gets up, and cold air gets down, take a very simplied formula of vertical air speed depending on local temperature gradient from the previous formula.
(Very roughly, nobody cares about exact values).

Now calculate local temperature and local vertical air speed absolutely like the horizontal one, as a net sum of values calculated for neighboring whirls.

***

So, you have, say 10 whirl center points, 10 pairs of whirls direction+speed numbers (along the circular trajectory), 10x2 pairs of coefficients (horizontal speed and temperature), and this gives you horizontal and vertical speeds and temperature at any point of a planet.

Make same for every winded planet.

Now you can easily generate more or less having sense winds from negligible amount of data being stored.

Where several whirls touch each other there can be "areas of turbulence", where speed is quickly varying with position change.
(It happens on its own, not to be implemented. Just net value of speed changes quickly, lol.)

***

Now you can visualise the whirls in some weather map window, as you know there positions.

***

Limit the whirl lifespan to prevent it constantly orbiting the planet. Let it pass random angle (90..270°) along its trajectory and destroy. Instead create a new whirl to keep their total number more or less constant.

***

Implement biome coefficients. Some biomes can enforce wind, others decrease.

***

You can also implement seasons by generating whirls at some points with coefficients corresponding to, say, planet position.

***

A visualised whirl.

Spoiler

267182449.jpg

 

Edited by kerbiloid
Link to comment
Share on other sites

@kerbiloid  that "visualized whirl" looks a lot like an Atlantic hurricane.  ;)

I've decided that the Island Base in our game was nearly destroyed by a visualized whirl... hence its poor state of disrepair.  Rather than rebuild their above ground Rescue Operations Center, they just dug-in to the adjacent mountain.  An elevator moves craft from the secret hangar to the spawn point.

Edit:  I for one, would love to fly a Whirl Hunter into the eye of a visualized whirl!

Edited by XLjedi
Link to comment
Share on other sites

9 minutes ago, kerbiloid said:

Isn't any Atlantic hurricane an atmospheric whirl?

Well sure!  ....and I think Kerbals would probably come up with their own kerbal-ish (somewhat comedic) name for such things. 

I like "Whirly Storm"  OH!  maybe "Whirlycane"  that's even better!

That would be my recommendation.  I'm going to use that in my own storylines now.

Edit:  need to start working on my storm hunter turboprop now.  I call dibbs on the "Whirly Hunter" name!

Edited by XLjedi
Link to comment
Share on other sites

4 hours ago, kerbiloid said:

Whirls.

As air masses like to move like huge whirls, maybe randomly create several 100..200 km (for Kerbin) wide whirls and calculate local wind speed and direction as their net speed.

Say, randomly generate several points (lat-long) as whirl centers, scattered across the planet surface. Invisible, just math coordinate points.

Let these whirl centers move along the planet along simple circles with slightly random constant speed, nearly like real air masses move.
Let every circular trajectory be tilted to equator at 0..60° (to not touch the poles). In fact, just make the whirl trajectory tilted at angle when it touches some circumpolar latitude with its upper edge.
So, at any moment you have exact position of every whirl center.

Add two more fixed points at both poles to have two circumpolar whirls. Absolutely same as others, but with fixed (+/-90° lat) coordinates.

Imagine whirls around every such point. Let them be enough wide to partially intersect with edges. Not visual, just imaginary whirls.

Take some very simplified formula for the horizontal (in fact, tangential, around the whirl vertical axis) wind speed value at radius from the whirl center and altitude. Anyway nobody cares about exact values.
Let the speed be the same at same radius and height, not depending on position angle. Just like a circular line around the whirl center.
This will give you both absolute value and direction of wind at any point of this whirl. (Value from radius and altitude. Wind direction is simply tangential, defined from angle relative to the whirl center.)

Randomly vary coefficients in the whirl formula to get slightly different values of wind speed in various whirls, from very weak whirls to hurricanes.

Calculate horizontal wind speed at any point as a vector sum of wind speeds calculated for whirls touching this point at this altitude.

Now you have local horizontal wind speed at any point of the planet surface by keeping in memory just 10 points and, say, 10x2 random coefficients.

***

Keep wind speed nearly zero at the whirl center to have an eye of hurricane.

***

Take very simplified basic formula of temperature (altitude).
As warm air gets up, and cold air gets down, take a very simplied formula of vertical air speed depending on local temperature gradient from the previous formula.
(Very roughly, nobody cares about exact values).

Now calculate local temperature and local vertical air speed absolutely like the horizontal one, as a net sum of values calculated for neighboring whirls.

***

So, you have, say 10 whirl center points, 10 pairs of whirls direction+speed numbers (along the circular trajectory), 10x2 pairs of coefficients (horizontal speed and temperature), and this gives you horizontal and vertical speeds and temperature at any point of a planet.

Make same for every winded planet.

Now you can easily generate more or less having sense winds from negligible amount of data being stored.

Where several whirls touch each other there can be "areas of turbulence", where speed is quickly varying with position change.
(It happens on its own, not to be implemented. Just net value of speed changes quickly, lol.)

***

Now you can visualise the whirls in some weather map window, as you know there positions.

***

Limit the whirl lifespan to prevent it constantly orbiting the planet. Let it pass random angle (90..270°) along its trajectory and destroy. Instead create a new whirl to keep their total number more or less constant.

***

Implement biome coefficients. Some biomes can enforce wind, others decrease.

***

You can also implement seasons by generating whirls at some points with coefficients corresponding to, say, planet position.

***

A visualised whirl.

  Hide contents

267182449.jpg

 

Pretty much along the lines of what I was considering ... although the weather, meaning global control of wind since wind itself works fantastically, won't be added in until after I'm done with the challenge builder/Geo-Cache deal which is the one of the main features I've been working on (almost done ... Geo-Caching works great)

I'll definitely be coming back to your post for reference :)

 

Edited by DoctorDavinci
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...