Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2005:
[Freeciv-Dev] Re: (PR#12806) idea: harsh climate generator
Home

[Freeciv-Dev] Re: (PR#12806) idea: harsh climate generator

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] Re: (PR#12806) idea: harsh climate generator
From: "Brian Dunstan" <bdunstan149@xxxxxxxxx>
Date: Sat, 16 Apr 2005 01:39:30 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12806 >

--- Jason Short <jdorje@xxxxxxxxxxxxxxxxxxxxx> wrote:
> 
> <URL:
> http://bugs.freeciv.org/Ticket/Display.html?id=12806
> >
> 
> Brian Dunstan wrote:
> 
> > OK, revision 2 of the patch does this. 
> Unfortunately
> > it has an awkward way of finding latitude.  I am
> > curious if there is simple and easy way to find a
> > linear measure of how far a tile is between the
> > equator and the pole.  This is easy in projection
> 1;
> > in projections such as 3, where you wrap both N-S
> and
> > E-W,  I could not find a simple way to do this. 
> 
> map_colatitude()
> 
> -jason

OK took a second look at it, seems that topology 3 is
a bit different than I thought.  Topology 3 has the
same proportion of temperatures as Topology 1, so they
are really using the same projection of 3d->2d
coordinates, just with a different visual presentation
of those 2d coordinates.

I think it is still OK to transform the latitude; this
will shrink the poles compared with topology 1.  This
is similar to how when you look at a globe, the poles
shrink when compared to a mercator projection map.  I
think this could help give the impression that the
user is viewing a 3-d map projected onto his 2-d
screen, especially when the screen is centered near
the polar regions.  It also helps in getting similar
looking maps when you use the same settings with
different projections.


This diff has a different comment but the code is the
same.


Brian


                
__________________________________ 
Do you Yahoo!? 
Plan great trips with Yahoo! Travel: Now over 17,000 guides!
http://travel.yahoo.com/p-travelguide
diff -Nur -Xfreeciv/diff_ignore freeciv/server/generator/mapgen.c 
freeciv_altered/server/generator/mapgen.c
--- freeciv/server/generator/mapgen.c   2005-04-15 23:03:26.224833520 -0400
+++ freeciv_altered/server/generator/mapgen.c   2005-04-16 00:33:36.084409856 
-0400
@@ -190,6 +190,10 @@
                                int thill, int my_height)
 {
   int higher_than_me = 0;
+
+  /* when steepness is very low, it's ok to get unending flatlands */
+  if(map.steepness <= 15) return FALSE;
+
   square_iterate(ptile, 2, tile1) {
     if (hmap(tile1) > thill) {
       return FALSE;
@@ -220,6 +224,10 @@
 static bool terrain_is_too_high(struct tile *ptile,
                                int thill, int my_height)
 {
+
+  /* when steepness is very high, it's ok to get unending mountains */
+  if(map.steepness >= 85) return FALSE;
+
   square_iterate(ptile, 1, tile1) {
     if (hmap(tile1) + (hmap_max_level - hmap_mountain_level) / 5 < thill) {
       return FALSE;
@@ -357,7 +365,7 @@
   } else if (tmap_is(ptile, TT_COLD)) {
     map_set_terrain(ptile, T_TUNDRA); 
   } else {
-    if (myrand(100) > 50) {
+    if(myrand(99) < map.wetness) {
       map_set_terrain(ptile, T_GRASSLAND);
     } else {
       map_set_terrain(ptile, T_PLAINS);
@@ -1136,26 +1144,49 @@
 **************************************************************************/
 static void adjust_terrain_param(void)
 {
+
+#define SQR(x) ((x)*(x))
+
   int polar = 2 * ICE_BASE_LEVEL * map.landpercent / MAX_COLATITUDE ;
   float factor = (100.0 - polar - map.steepness * 0.8 ) / 10000;
 
+  int remaining = 0;
+  
+  /* this must be done to prevent div0 errors later on */
+  int t = MIN(map.temperature, 99);
+  
+  int steep_sqrt = (int)(100.0 * 
+                       sqrt((float)map.steepness / 100.0));
 
   mountain_pct = factor * map.steepness * 90;
-
-  /* 27 % if wetness == 50 & */
-  forest_pct = factor * (map.wetness * 40 + 700) ; 
-  jungle_pct = forest_pct * (MAX_COLATITUDE - TROPICAL_LEVEL) /
-               (MAX_COLATITUDE * 2);
+  
+  /* Make sure terrain proportions come out close to what you'd expect:
+   * No deserts on wet planets, no swamps on dry ones, 
+   * no jungles on frozen ones.  Interpolate as necessary */
+  
+  river_pct = SQR(map.wetness) / SQR(100); 
+  remaining = 100 - mountain_pct;
+  
+  /* forests: adaptable. prefer terrain steep or wet */
+  forest_pct = (steep_sqrt + map.wetness)/2;
+  forest_pct = (remaining*forest_pct)/100;
+  remaining -= forest_pct;
+  
+  /* jungles: require terrain hot.  Prefer either wet or steep */
+  jungle_pct = (forest_pct * SQR(t)) / SQR(100);
   forest_pct -= jungle_pct;
-
-  /* 3 - 11 % */
-  river_pct = (100 - polar) * (3 + map.wetness / 12) / 100;
-
-  /* 6 %  if wetness == 50 && temperature == 50 */
-  swamp_pct = factor * MAX(0, 
-                          (map.wetness * 9 - 150 + map.temperature * 6));
-  desert_pct =factor * MAX(0,
-               (map.temperature * 15 - 250 + (100 - map.wetness) * 10)) ;
+  
+  /* deserts: require terrain hot and dry */
+  desert_pct = (SQR(t) * remaining) / SQR(100);
+  desert_pct = (SQR(100 - map.wetness) * desert_pct) / SQR(100);
+  remaining -= desert_pct;
+  
+  /* swamp: prefer terrain hot and wet.  Require terrain flat */
+  swamp_pct = (t*map.wetness*remaining) / SQR(100);
+  swamp_pct = (swamp_pct * SQR(100-steep_sqrt)) / SQR(100);
+  remaining -= swamp_pct;
+  
+#undef SQR
 }
 
 /****************************************************************************
diff -Nur -Xfreeciv/diff_ignore freeciv/server/generator/temperature_map.c 
freeciv_altered/server/generator/temperature_map.c
--- freeciv/server/generator/temperature_map.c  2005-04-15 23:03:26.223833672 
-0400
+++ freeciv_altered/server/generator/temperature_map.c  2005-04-16 
01:15:28.393480824 -0400
@@ -73,6 +73,8 @@
 {
   int i;
 
+#define SQR(x) ((x)*(x))
+
   /* if map is defined this is not changed */
   /* TO DO load if from scenario game with tmap */
   assert(temperature_map == NULL); /* to debug, never load a this time */
@@ -82,13 +84,39 @@
 
   temperature_map = fc_malloc(sizeof(*temperature_map) * MAP_INDEX_SIZE);
   whole_map_iterate(ptile) {
-  
-     /* the base temperature is equal to base map_colatitude */
-    int t = map_colatitude(ptile);
+          
+    /* to the extent planetary temperature differs from 50, 
+     * expand influence of very low planet temperatures to the equator,
+     * and the influence of very high planet temperature to the poles */
+    int planetary_temperature = (map.temperature * MAX_COLATITUDE)/100;
+    int harshness = SQR(100-2*map.temperature);
+    int mildness = SQR(100) - harshness;
+
+    /* the base temperature is equal to base map_colatitude
+     * t=0 is the pole, t=MAX_COLATITUDE is the equator */
+    int t = map_colatitude(ptile); 
+    
+    /* if you compare a mercator map to looking at a globe, the view
+     * of a spherical globe will show much smaller polar regions compared
+     * to the mercator projection.  The 'wrap Y' topologies in freeciv
+     * appear as if you are looking at a real globe, rather than mercator
+     * projection.  This formula gives an approximation of the resulting
+     * shrinkage of the polar regions with respect to equitorial regions.
+     * The approximation treats the globe as an octahedron for the purpose
+     * of calculating cumulative surface area as a function of latitude */
+    float f_colatitude = (float)t / (float)MAX_COLATITUDE; 
+
+    if(topo_has_flag(TF_WRAPY)) {
+      t = (int)(sqrt(f_colatitude) * (float)MAX_COLATITUDE);
+    }
+
+    t += ((harshness * planetary_temperature) + (mildness * t)) / SQR(100);
+    t /= 2;
+    
     if (!real) {
       tmap(ptile) = t;
     } else {
-      /* height land can be 30% collest */
+      /* high land can be 30% cooller */
       float height = - 0.3 * MAX(0, hmap(ptile) - hmap_shore_level) 
          / (hmap_max_level - hmap_shore_level); 
       /* near ocean temperature can be 15 % more "temperate" */
@@ -99,13 +127,7 @@
       tmap(ptile) =  t * (1.0 + temperate) * (1.0 + height);
     }
   } whole_map_iterate_end;
-  /* adjust to get well sizes frequencies */
-  /* Notice: if colatitude is load from a scenario never call adjust has
-             scenario maybe has a odd colatitude ditribution and adjust will
-            brack it */
-  if (!map.alltemperate) {
-    adjust_int_map(temperature_map, MAX_COLATITUDE);
-  }
+
   /* now simplify to 4 base values */ 
   for (i = 0; i < MAP_INDEX_SIZE; i++) {
     int t = temperature_map[i];
@@ -120,4 +142,6 @@
       temperature_map[i] = TT_FROZEN;
     }
   } 
+
+#undef SQR
 }

[Prev in Thread] Current Thread [Next in Thread]