Sunday, January 26, 2014

Hextonics

Updated the old tectonics simulation to work on the mostly-hex grid. It was relatively painless: most of the codebase had been written with the idea of "tiles" on a planet just being points on the unit sphere, each with some arbitrary number of neighbors.

The climate model, such as it is, was pretty much hacked in from earlier experimental code that had made more assumptions about data structures, so there was some refactoring to take care of there. But otherwise it seems to work like before, just on a bunch of hexes instead of a bunch of rectangles.

Two sides of a planet:
Two large continents and some islands

Smaller continents with mountains
Source here: https://github.com/tps12/Tec-Nine/commit/2f49be89c5d36a5ca1b8236e9aa6044d51ee4a9d

Sunday, November 3, 2013

Tiling a Sphere With Mostly Hexagons

I saw this thing where a person generates planets using a grid that looks like a bunch of hexagons: https://github.com/vraid/earthgen-old

Hexagon-based grids are popular for things like strategy games, because adjacent tiles are separated by a constant distance. I used the math from vraid's code as the basis for a demo of this kind of tiling system. This video shows sphere tiled with RGB colors based on each tile's vector location on the unit sphere, and a 2D detail view for navigating around a local region of the grid:

The grid starts as a dodecahedron (made of twelve pentagons), and each vertex is squashed into a hexagon to produce a soccer ball shape. That process is repeated to create each higher resolution grid. This video demonstrates the process, sampling from ETOPO1 data to color each tile:
One really cool thing is that you can define these grids lazily, with hex locations determined for only a small region of the sphere at a given resolution.

You can imagine a game where an entire planet's climate is simulated with 500km tiles, the weather for a single continent is simulated with 10km tiles, battles take place on a grid of 10m tiles, and hand-to-hand combat on a grid of 1m tiles. (The memory cost to store even a single byte of data for each tile of a planet-sized sphere at this resolution would be prohibitive.)

This video shows a grid lazily subdivided to achieve this kind of resolution, using a noise function to color the tiles:
As mentioned above, the grid begins as a grid of pentagons. At each iteration of the vertex-squashing process, the previous grid's faces are carried over to the new one with the same number of sides and centered at the same location on the unit sphere; while each of the previous grid's vertices becomes a hexagonal face of the new grid.

As a consequence, the twelve initial pentagons can be found in the grid for each resolution. Trying to render these in a 2D local view can be challenging as they necessarily break up the hex grid. This video shows one option (other people who have talked about these kinds of grids, again in a game context, have proposed putting mountains or seas or some other inaccessible feature around each of the pentagon locations, to avoid having to deal with this entirely):
Code for my demo program is at https://github.com/tps12/hey-grid. Also vraid appears to be rewriting their code in Racket, which is interesting.

Friday, May 31, 2013

One Less MetroCard

I always thought "One Less MetroCard" would make a funny bike sticker in New York, where realistically very few bicycle commuters are opting out of driving a private car.

The new bike share is awesome, and the enormous corporate logos provide lots of good re-purposable real estate:
"One Less MetroCard" bumper sticker
Zazzle wouldn't print it for me due to copyright issues, but trying an alternative.

Saturday, February 2, 2013

Geologeez Nutz

Not done anything lately on tectonics simulations, but I realized that there was a bunch of crap I'd done last fall that I had never posted about, so thought I'd describe it, to remind myself where I left everything if for no other reason.

The main change was making tiles have layers of rock instead of just single elevation values, and different rock types for each layer.

The first continent is a hunk of igneous extrusive rock of varying composition, and the planet begins with no atmosphere or life:

Initial supercontinent with no life

When the atmosphere kicks in then you get erosion, which varies based on climate and grinds layers from the top down to create sedimentary rock of progressively smaller grain sizes.

When life shows up there is an additional organic component to sediments, which makes limestone and chalk in the right environment that can in turn make marble, though probably too rarely. Life marks tiles as having peat bogs where it makes sense as well, so there's the potential to figure out where fossil fuels end up.

Crustal thickness leads to regional metamorphism, and subduction causes igneous intrusions with associated contact metamorphism. Erosion affects rocks based on how tough they are, so fresh mountains should grind down to craggy hornfels and granite shields should eventually emerge.

The merging of tiles due to the constraints of math on a sphere tries to preserve uniqueness, so peak elevations and metamorphic layers don't get averaged away. Not scientifically justifiable, really.

I added the ability to click on a tile (in the Mercator and Sinusoidal projections) and see the layers of that tile, with a tooltip showing the full composition of a given layer. I also added the crappy "color" display mode that mostly just suddenly turns green when life shows up and then shows you where mountains are:

Layer information with composition tooltip

I also did some profiling that led to some optimizations, mainly around the bogus climate model but also caching various calculations that were repeated all over the place. This got things moving quick enough that I could start thinking about supercontinent cycles again, but none of the various forays I made into getting any of that to work out nicely panned out.

Planet with a couple continents showing different climates

The other improvement in the offing is figuring out metals, basically banded iron formations and the veins of stuff that go along with igneous intrusions and create placer deposits when they erode.

Also found a dude on Reddit who has a similarly-conceived project, pyTectonics. He's taken a more scientifically rigorous approach and does things on a Fibonacci grid, which looks pretty awesome. I'm not exactly sure, but it also sounds like he creates and destroys new grid points as needed, which is a cool idea.

Edit: Forgot to link to the source.

Thursday, December 27, 2012

Monday, August 20, 2012

Mountain? Climate!

I had put together a crappy climate model before I had really read anything about meteorology: basically, vary insolation based on season, have prevailing winds pick up moisture from the sea and rain it down according to elevation, and then use the results to classify the climate.

So no meandering jet streams or mid-latitude cyclones or anything, but I've had enough trouble even figuring out where to start on a more legitimate climate and weather simulation that I decided to just bring the old broken one into the tectonics simulation as a placeholder.

Here's my fake climate simulation at work:
World map with Koeppen categorizations that are all wrong.
Note the great Saudi Arabian jungle, the desert in the Southeast US (but not the Southwest), the frozen British Isles, &c.

So despite the brokenness, I wanted to get some sort of climate system in so it could contribute to the erosion algorithm, modulating the erosion amount from each tile by its annual precipitation and "polar" status (on the theory that glaciers cause a lot of erosion regardless of precipitation).

Compare erosion under the old algorithm (reddishness represents height lost to erosion, greenishness height gained by deposited eroded sediment):
World map showing erosion rates based solely on relative elevation;
versus the new erosion modulated by precipitation:
World map showing erosion rates based on relative elevation and climate.

I had to tweak a magic number that had been picked to keep mountain building and erosion somewhat in balance. But after that, a newly created world came out looking pretty good:
A generated world map;
and its "climate":
Crappy climate map of the previous generated world.

In any case, it doesn't really change the current simulation very much, but it does lay the groundwork for some more interesting recording of geological history. Source.

Friday, August 3, 2012

Fixing a Hole

My previous "plates on a sphere" simulation tended make continents that were too round. This was because of how I tried to resolve an issue stemming from my whole approach to the spherical geometry.

The sphere is divided into "tiles" of approximately equal size, each with a fixed location (a vector on the unit sphere). So at any point in time, a continent is defined as a set of those tiles.

When a continent moves, the vectors of all of its tiles are moved (that is, rotated around an axis) by a given amount; then the closest tile to each of those resulting vectors gets the value of its source tile.

Because of how the tiles are distributed (near the equator, almost a grid; at the poles, not anything like a grid), there is never a neat 1-to-1 mapping of source to destination tiles (unless the continent is centered on the equator, moving due West or East).

Which means there are lots of instances of more than one source tile mapping to the same destination tile, and tiles that are visibly part of the continent in its final position but that weren't mapped to by any source tile, and thus appear as holes.

My previous solution to this problem had been, at each step, to map each source tile to the nearest two destination tiles; to prevent the continent from growing out of control, I then trimmed off a bunch of tiles, starting with those most distant from the middle of the continent. This caused the progressive roundening, which sort of makes intuitive sense (sharp edges ground down over time) but doesn't look very realistic (Earth has lots of pointy continents).

My new strategy is to identify potential holes (tiles adjacent to those identified as belonging to the continent in its new position but that aren't themselves part of the continent's set of tiles), and rotate their positions backwards to see if the nearest tile to that location was part of the old set. If so, then add it to the new set, then check the tiles adjacent to that one, and so forth.

The resulting continents are much more satisfyingly pointy: