Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2003:
[Freeciv-Dev] (PR#6259) iso-map versions of native<->map pos conversion
Home

[Freeciv-Dev] (PR#6259) iso-map versions of native<->map pos conversion

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#6259) iso-map versions of native<->map pos conversion macros
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 23 Sep 2003 13:35:36 -0700
Reply-to: rt@xxxxxxxxxxxxxx

For iso-maps to work native coordinates have to work for them.  This 
patch changes native_to_map_pos, map_to_native_pos, map_to_native_x, and 
map_to_native_y to do that.  I also add a section to doc/HACKING.

This doesn't mean iso-maps will fully work yet, though.  So there's 
really no way to test this code outside of the rest of the patch 
(gen-topologies.diff in the 'patches' module of the freeciv-test 
repository).

This patch deserves scrutiny since the math is pretty obscure.

jason

? rc
Index: common/map.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/map.h,v
retrieving revision 1.154
diff -u -r1.154 map.h
--- common/map.h        2003/09/23 19:47:22     1.154
+++ common/map.h        2003/09/23 20:30:27
@@ -235,15 +235,28 @@
 #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 native_to_map_pos(pmap_x, pmap_y, nat_x, nat_y)                     \
+  (topo_has_flag(TF_ISO)                                                    \
+   ? (*(pmap_x) = ((nat_y) + ((nat_y) & 1)) / 2 + (nat_x),                  \
+      *(pmap_y) = (nat_y) - *(pmap_x) + map.xsize)                          \
+   : (*(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_to_native_pos(pnat_x, pnat_y, map_x, map_y)                     \
+  (topo_has_flag(TF_ISO)                                                    \
+   ? (*(pnat_y) = (map_x) + (map_y) - map.xsize,                            \
+      *(pnat_x) = (2 * (map_x) - *(pnat_y) - (*(pnat_y) & 1)) / 2)          \
+   : *(pnat_x) = (map_x), *(pnat_y) = (map_y))
 
 /* Use map_to_native_pos instead unless you know what you're doing. */
-#define map_pos_to_native_x(map_x, map_y) (map_x)
-#define map_pos_to_native_y(map_x, map_y) (map_y)
+#define map_pos_to_native_x(map_x, map_y)                                   \
+  (topo_has_flag(TF_ISO)                                                    \
+   ? (((map_x) - (map_y) + map.xsize                                        \
+       - (((map_x) + (map_y) - map.xsize) & 1)) / 2)                        \
+   : (map_x))
+#define map_pos_to_native_y(map_x, map_y)                                   \
+  (topo_has_flag(TF_ISO)                                                    \
+   ? ((map_x) + (map_y) - map.xsize)                                        \
+   : (map_y))
 
 #define map_pos_to_index(map_x, map_y)        \
   (CHECK_MAP_POS((map_x), (map_y)),           \
Index: doc/HACKING
===================================================================
RCS file: /home/freeciv/CVS/freeciv/doc/HACKING,v
retrieving revision 1.12
diff -u -r1.12 HACKING
--- doc/HACKING 2003/07/23 20:24:36     1.12
+++ doc/HACKING 2003/09/23 20:30:27
@@ -556,6 +556,49 @@
 systems, they will have to be refined.
 
 =========================================================================
+Native coordinates on an isometric map
+=========================================================================
+
+An isometric map is defined by the operation that converts between map
+(user) coordinates and native (internal) ones.  In native coordinates, an
+isometric map behaves exactly the same way as a standard one.  (See
+"native coordinates", above.
+
+Converting from map to native coordinates involves a pi/2 rotation (which
+scales in each dimension by sqrt(2)) followed by a compression in the X
+direction by a factor of 2.  Then a translation is required since the
+"normal set" of native coordinates is defined as
+  {(x, y) | x: [0..map.xsize) and y: [0..map.ysize)}
+while the normal set of map coordinates must satisfy x >= 0 and y >= 0.
+
+Converting from native to map coordinates (a less cumbersome operation) is
+the opposite.
+                                        EJ
+           ABCDE     A B C D E         DIO
+  (native) FGHIJ <=>  F G H I J <=>   CHN  (map)
+           KLMNO     K L M N O       BGM
+                                    AFL
+                                     K
+
+Note that
+
+  native_to_map_pos(0, 0) == (0, map.xsize-1)
+  native_to_map_pos(map.xsize-1, 0) == (map.xsize-1, 0)
+  native_to_map_pos(x, y+2) = native_to_map_pos(x,y) + (1,1)
+  native_to_map_pos(x+1, y) = native_to_map_pos(x,y) + (1,-1)
+
+The math then works out to
+
+  map_x = ceiling(nat_y / 2) + nat_x
+  map_y = floor(nat_y / 2) - nat_x + map.xsize - 1
+
+  nat_y = map_x + map_y - map.xsize
+  nat_x = floor(map_x - map_y + map.xsize / 2)
+
+which leads to the macros native_to_map_pos, map_to_native_pos,
+map_pos_to_native_x, and map_pos_to_native_y that are defined in map.h.
+
+=========================================================================
 Unknown tiles and Fog of War
 =========================================================================
 

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#6259) iso-map versions of native<->map pos conversion macros, Jason Short <=