Complete.Org: Mailing Lists: Archives: freeciv-dev: April 2003:
[Freeciv-Dev] Re: (PR#3936) introducing native coordinates
Home

[Freeciv-Dev] Re: (PR#3936) introducing native coordinates

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients:;
Subject: [Freeciv-Dev] Re: (PR#3936) introducing native coordinates
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 6 Apr 2003 14:08:19 -0700
Reply-to: rt@xxxxxxxxxxxxxx

Gregory Berkolaiko wrote:
> On Sat, 5 Apr 2003, Jason Short wrote:
> 
> 
>>Jason Short wrote:
>>
>>
>>>Ugh.  Same patch - better grammar.
>>
>>Sigh - and here is the patch...
> 
> 
> In here:
> 
> +  while its representation in map coordinates would be
> +
> +                     XX                   (2,0)
> +                    XXX  <=>        (1,1) (2,1) (3,1)
> +                   XXX        (0,2) (1,2) (2,2)
> +                    X               (1,3)
> 
> there are 9 crosses on the left and only 8 pairs on the right.

Oops.

> Also, I wanted picture like this
> 
> +        25        0 1 2         012
> +       148   <=>   3 4 5   <=>  345
> +      037         6 7 8         678
> +       6
> 
> to aid understanding how you transform 
>       X X X
>        X X X
>       X X X
> into
>                      XX
>                     XXX
>                    XXX
>                     X
> 
> But where you put it, it's already too late, the reader would either have 
> understood it or would have given up.

How about this?  I don't have the full picture, but the positions are at 
list ordered from one picture to the next.

jason

Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.143
diff -u -r1.143 map.h
--- common/map.h        2003/04/04 15:47:49     1.143
+++ common/map.h        2003/04/06 20:51:54
@@ -226,6 +226,12 @@
 #define map_adjust_y(Y) \
   (((Y)<0) ? 0 : (((Y)>=map.ysize) ? map.ysize-1 : (Y)))
 
+#define native_to_map_pos(pmap_x, pmap_y, nat_x, nat_y) \
+  (*(pmap_x) = (nat_x), *(pmap_y) = (nat_y))
+
+#define map_to_native_pos(pnat_x, pnat_y, map_x, map_y) \
+  (*(pnat_x) = (map_x), *(pnat_y) = (map_y))
+
 #define map_pos_to_index(map_x, map_y)        \
   (CHECK_MAP_POS((map_x), (map_y)),           \
    (map_x) + (map_y) * map.xsize)
Index: doc/HACKING
===================================================================
RCS file: /home/freeciv/CVS/freeciv/doc/HACKING,v
retrieving revision 1.9
diff -u -r1.9 HACKING
--- doc/HACKING 2003/02/17 02:11:26     1.9
+++ doc/HACKING 2003/04/06 20:51:56
@@ -408,6 +408,116 @@
 be used.
 
 =========================================================================
+Different coordinate systems
+=========================================================================
+
+In Freeciv, we have the general concept of a "position" or "tile"; this
+is self-explanatory.  However, a tile can be referred to in any of several
+coordinate systems.  The distinction becomes important we start to use
+non-standard types of maps.
+
+- Map (or "standard") coordinates.
+
+  All of the map manipulation examples above are in map coordinates.
+  These preserve the local geometry of square tiles, but do not represent
+  the global map geometry well.  In map coordinates, you are guaranteed
+  (so long as we use square tiles) that the tile adjacency rules
+
+      (map_x-1, map_y-1)    (map_x, map_y-1)   (map_x+1, map_y-1)
+      (map_x-1, map_y)      (map_x, map_y)     (map_x+1, map_y)
+      (map_x-1, map_y+1)    (map_x, map_y+1)   (map_x+1, map_y+1)
+
+  are preserved, regardless of what the underlying map or drawing code
+  looks like.  This is the definition of this system.
+
+  Map coordinates are easiest for local operations (like square_iterate
+  or adjc_iterate) but unwieldy for global operations.
+
+- Native coordinates.
+
+  With an iso-rectangular map, global operations are difficult using map
+  coordinates.  Imagine a simple iso-rectangular map.  Its "natural"
+  representation is
+
+                 A B C        (0,0)   (2,0)   (4,0)
+                  D E F  <=>      (1,1)   (3,1)   (5,1)
+                 G H I        (0,2)   (2,2)   (4,2)
+
+  while its representation in map coordinates would be
+
+                     CF                   (2,0) (3,0)
+                    BEI  <=>        (1,1) (2,1) (3,1)
+                   ADH        (0,2) (1,2) (2,2)
+                    G               (1,3)
+
+  Neither is particularly good for a global map operation such as
+  whole_map_iterate.  Something better is needed.
+
+  Native coordinates compress the map into a continuous rectangle, the
+  dimensions are defined as map.xsize x map.ysize.  For instance the
+  above iso-rectangular map is represented in native coordinates by
+  compressing the natural representation in the X axis to get the
+  3x3 iso-rectangle of
+
+                    ABC       (0,0) (1,0) (2,0)
+                    DEF  <=>  (0,1) (1,1) (2,1)
+                    GHI       (0,2) (1,2) (3,2)
+
+  The resulting coordinate system is much easier to use than map
+  coordinates in a very limited number of operations.  These include
+  most internal topology operations (e.g., normalize_map_pos,
+  whole_map_iterate) as well as storage (in map.tiles and savegames,
+  for instance).
+
+  In general, native coordinates can be defined based on this property:
+  the basic map becomes a continuous (gap-free) cardinally-oriented
+  rectangle when expressed in native coordinates.
+
+- Index coordinates.
+
+  Index coordinates simply reorder the map into a continous (filled-in)
+  one-dimensional system.  For instance the above iso-rectangular map
+  would look like
+
+        25        0 1 2         012     
+       148   <=>   3 4 5   <=>  345   <=> 012345678
+      037         6 7 8         678
+       6
+
+  in index coordinates.  This coordinate system is closely tied to
+  the ordering of the tiles in native coordinates, and is slightly
+  easier to use for some operations (like storage) because it is
+  one-dimensional.
+
+- Natural coordinates.
+
+  These have been hinted at above, but are not actually used in Freeciv.  But
+  they are very helpful for human understanding of non-standard maps.
+
+  Natural coordinates preserve the geometry of map coordinates, but also have
+  the rectangular property of native coordinates.  They are unwieldy for
+  some operations because of their sparseness - they may not have the same
+  scale as map coordinates and, in the iso case, there are gaps in the
+  natural representation of a map.
+
+  For an isometric map, natural coordinates are the same as "isometric
+  coordinates".
+
+With a standard rectangular map, map and native coordinates are
+equivalent.  When we introduce isometric maps, the distinction becomes
+important, as demonstrated above.  Many places in the code have
+introduced "map_x/map_y" or "nat_x/nat_y" to help distinguish whether
+map or native coordinates are being used.  Other places are not yet
+rigorous in keeping them apart, and will often just name their variables
+"x" and "y".
+
+Note that map.xsize and map.ysize define the dimension of the map in
+_native_ coordinates.
+
+Of course, if a future topology does not fit these rules for coordinate
+systems, they will have to be refined.
+
+=========================================================================
 Unknown tiles and Fog of War
 =========================================================================
 
Index: server/gamelog.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamelog.c,v
retrieving revision 1.27
diff -u -r1.27 gamelog.c
--- server/gamelog.c    2003/04/04 15:47:49     1.27
+++ server/gamelog.c    2003/04/06 20:51:56
@@ -93,16 +93,13 @@
 
 void gamelog_map(void)
 {
-  int x, y;
+  int nat_x, nat_y, map_x, map_y;
   char *hline = fc_calloc(map.xsize+1, sizeof(char));
 
-  for (y = 0; y < map.ysize; y++) {
-    for (x = 0; x < map.xsize; x++) {
-      if (regular_map_pos_is_normal(x, y)) {
-       hline[x] = is_ocean(map_get_terrain(x, y)) ? ' ' : '.';
-      } else {
-       hline[x] = '#';
-      }
+  for (nat_y = 0; nat_y < map.ysize; nat_y++) {
+    for (nat_x = 0; nat_x < map.xsize; nat_x++) {
+      native_to_map_pos(&map_x, &map_y, nat_x, nat_y);
+      hline[nat_x] = is_ocean(map_get_terrain(map_x, map_y)) ? ' ' : '.';
     }
     gamelog(GAMELOG_MAP, "%s", hline);
   }

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