Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2001:
[Freeciv-Dev] Re: example patch: [xy]_map_iterate
Home

[Freeciv-Dev] Re: example patch: [xy]_map_iterate

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxxxxxxxxxxx
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: example patch: [xy]_map_iterate
From: Raimar Falke <hawk@xxxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 4 Oct 2001 18:39:48 +0200
Reply-to: rf13@xxxxxxxxxxxxxxxxxxxxxx

On Thu, Oct 04, 2001 at 09:47:19AM -0400, Jason Dorje Short wrote:
> [Note: this explanation is long and repetitious.  I'm trying to be as
> clear as possible.]
> 
> Raimar Falke wrote:
> 
> > Now I have another basic question:
> > 
> >    a
> >   bcd
> >  efghi
> >   jkl
> >    m
> > 
> > For which tiles is y==0? a OR e,b and a? Or isn't this an isometric
> > map? And the following is:?
> 
> It is an isometric map, but not a correct one if you desire wrapping. 
> It can't wrap properly.  A correction would be:
> 
>   a     <- y==0
>  bcd    <- y==1
> efghi      ...
>  jkln      ...
>   mo    <- y==4
> 
> ^   ^
> |   |
> |   x==4
> |
> x==0
> 
> With the addition of n and o it will now successfully wrap in one
> direction.  y==0 for just tile a.

This means that wrapping need a odd number in this axis?

> > 
> >         / North
> >    n  /
> >   o p
> >  q r s
> >   t u
> >    v
> > 
> > The same map rotated (non-isometric now):
> > 
> >  n p s
> >  o r u
> >  q t v
> 
> These two pictures are the same map, but a fundamentally different one
> from the one above.  This is a normal 3x3 map.  The first picture is the
> way it might be displayed with an isometric tileset, the second is how
> it is displayed with a "regular" (cartesian) tileset and also how both
> server and client track it internally.  The problem is that under
> isometric view, the map is all tilted!  It's pretty ugly.
> 
> Doing the same transformation on the first map, we see that
> 
>   a
>  bcd
> efghi
>  jkln
>   mo
> 
> is the same as
> 
> a d i
>  c h n
> b g l
>  f k o
> e j m
> 
> Hopefully you now understand everything :-).
> 
> As you can see it will look much better when *viewed* isometrically.  I
> think you are confusing an isometric *map* with an isometric *view*. 
> The second one we have - it requires a lot of very ugly math in the
> client code.  The first one we are not even close to being able to do -
> it requires a little bit of ugly code in the server AND everything else
> has to be fixed to use the proper map macros and functions.


> Putting these directions onto the cartesian representation of the map,
> we see that "north" is up-left, "south" is down-right, "east" is
> up-right, and "west" is down-left.  Everything's just rotated 45
> degrees.  (Note: you can really rotate it 45 degrees in either
> direction, but you need to take care that its the same direction every
> time.  I don't remember which way the client rotates things, but we
> should consider that before choosing.)

If this paragraph is about an isometric *map*: This means that a is
the only tile with y==0. But a,d and i are in the north?! Ohh my.

> > The adjacent property is the same.
> > 
> >        /
> > -     # \4
> > |    # # \
> > |   # # #  \/
> > 6    # # #
> > |     # # \
> > -      # / 3
> >         \
> > 
> >     |--6-|
> > 
> > The game has to know somewhere the this map above is 3x4.
> 
> Again, it *is* 3x4.  The server would never think of a regular map in
> this odd way; it always uses strictly cartesian coordinates.  This is
> how you would view it in the client isometrically; so unfortunately the
> client is forced to think of it this way (although it still thinks of it
> the cartesian way and makes the conversion each time it draws anything).
> 
> > The more I think about this the more I think that the easiest way is
> > to leave the current system in place and introduce a new name/position
> > space. Normal positions are called map positions and the new ones are
> > called user positons. If there is a non-isometric map there would a
> > 1:1 mapping of map pos to user pos and back. If there is a isometric
> > map is used the mapping would be more complicated. Neighbor properties
> > and distances are only defined on user positions.
> 
> You definitely do not understand.
> 
> Client-side, this is basically what is done now.  But that's for an
> isometric *view*, not an isometric map.
> 
> An isometric map is still cartesian.  The directions are still all the
> same.  It's just a different shape, and wraps differently.  So "the
> current system" as (I think) you are thinking of it will still work; all
> of the changes will be restricted to a few macros and functions within
> map.[ch].  But it's simply not possible to make the transformation as
> some sort of wrapper as you seem to be suggesting - that's what the
> client does with its isometric view, and it is something entirely
> different.
> 
> All of the changes now come because the current code assumes the
> topology is rectangular and wraps in one direction.  This code must be
> replaced by code that does not make these assumptions, but instead uses
> the correct macros and function calls: is_normal_map_pos instead of
> map_adjust_[xy], whole_map_iterate instead of for(x...) for(y...),
> is_real_tile instead of (y>=0 && y<map.ysize), etc.

You give a precise list of what has to be changed (not the cleanup but
the actual things). You can also formulate this in mathematical
ways. I still haven't got all difference between the map now and an
isometric map.

> > Summary: before I don't understand this issue and especially the end
> > result fully there will be no changes by me.
> 
> A wise plan in general, but with most of these changes I think it'll be
> clear that they are cleanups to the code that make things better and
> remove the assumptions above.

I agree. But for the changes to savegame I have to know the end result.

> > What
> > coordinates/positions are there? What semantic they represent (where
> > is north and south)?
> 
> Here is an isometric map as the user would see it under isometric
> tileset:
> 
> a d i
>  c h n
> b g l
>  f k o
> e j m
> 
> I think this is the easiest way to visualize it.  North, south, east,
> and west are obvious.  Note that this map can wrap east-west, but cannot
> possibly wrap north-south - the tiles won't line up.  If you try to do
> any actual calculations with this representation, though, it's very
> difficult - hence the difficulty of having an isometric tileset.
> 
>   a
>  bcd
> efghi
>  jkln
>   mo
> 
> This is how the server will represent it, and almost all current
> operations will continue to still work.
> 
> The most likely way it'll store the data is in a 5x5 array, although
> this wastes space.  A more general method would be in a single-index
> array using map_pos_to_index to index into it (it's more general because
> it can easily be extended to more extreme topologies).

How complex would the transformation methods?

> Almost all calculations can be done exactly the same way on this
> isometric map as on the current map.  The neighbor property remains
> exactly the same.  The only real differences are with border tiles,
> wrapping/normalcy, and realness. 

> is_real_tile and normalize_map_pos will contain some rather
> complicated code that will take some time to understand

You know that normalize_map_pos is used A LOT of times?! You will get
a real slowdown.

> (if you don't believe me, look at the transformations Thue does to
> get an isometric view).

Where?

> Also whole_map_iterate and the like
> won't work as-is because you can't iterate over it rectangularly; but
> you can still either iterate over the whole 5x5 space and filter out the
> bad positions or iterate over the index and use index_to_map_pos.

Ack.

> This issue really doesn't affect the [xy]_map_iterate I've been
> proposing; they're not directly needed because of the isometric map
> but are needed because some places can't use whole_map_iterate to do
> the iteration. The reason these changes are important for the
> isometric map is that the filter (on is_normal_map_pos) is still
> needed and will have to be added (we could theoretically go ahead
> and write the for loops out in each case and filter for normal
> coordinates manually...but it's better to have the macros do it).
> 
> Counting the dimensions of an isometric map is tricky as well.  You can
> think of the above map as a 6x5 isometric map (see the isometric
> representation).  It therefore has 6x5/2==15 tiles.  (The 2 factor comes
> because we're overcounting by a factor of sqrt(2) in each direction.)  A
> map will only wrap in a direction if its dimension is even (as opposed
> to odd) in that direction.  (Clarification: if you have a 5x5 map you
> get 5x5/2=12.5 tiles.  This is because the 5x5 map can be drawn to have
> either 12 or 13 tiles.  In the above example, remove either the leftmost
> or rightmost column (isometric view) to see.)  Alternately, you could
> count the map as a 3x2.5 isometric map; in this case you'd probably want
> to impose the restriction of integer dimensions (which also assures
> wrapping).  In this case the number of tiles is 3x2.5x2=15 tiles.  (This
> time the 2 factor comes because we're undercounting by a factor of
> sqrt(2) in each direction.)
> 
> Understand this: I'm not currently proposing anything directly related
> to an isometric map.  All of my proposed patches to date are merely
> cleanups that make the changes I mentioned above.  The only thing that
> isn't directly productive is that we filter over normal tiles in my most
> recent patch.  However, this also makes possible other things that have
> been proposed like invalid tiles in the middle of the map that represent
> impassable mountains - so again they're not directly related to an
> isometric map.  We also make possible other simpler things like wrapping
> the rectangular map in different directions (which Ross's patch already
> accomplishes, but does not do so in the correct manner because it still
> assumes a rectangular map).  In short: all we're doing at this point is
> removing assumptions from the code.
> 
> I don't think it's entirely necessary that you understand isometric
> maps.  Once all assumptions in the code are removed, a very few pieces
> of code will have to deal with the isometricness: normalize_map_pos,
> is_normal_map_pos, is_real_tile, index_to_map_pos, and map_pos_to_index
> may be all.  The act of removing those assumptions has nothing to do
> with isometric maps itself; it applies equally well to other maps like
> 
>      ^ ^ ^
>      | | |
> <- a b c d
> <- e f g h   /* weird approximation of a hemisphere */
> <- i j k l
> 
> <- a b c d e ->
> <- f g   i j -> /* an invalid position to signify
> <- k l m n o ->    impassable mountains */
> 
> We are a very long way off from having an actual isometric map.

*puh* Long email.

Ok next question: how should an isometric savegame look like?

1)
 a d i
  c h n
 b g l
  f k o
 e j m

2)
 adi
 chn
 bgl
 fko
 ejm

3)
   a
  bcd
 efghi
  jkln
   mo

I still have problems with the fact that less y doesn't mean more
north.

        Raimar

-- 
 email: rf13@xxxxxxxxxxxxxxxxx
 "Make it idiot-proof and someone will make a better idiot."


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