Complete.Org: Mailing Lists: Archives: freeciv-dev: November 2001:
[Freeciv-Dev] Re: topology RFC (again)

[Freeciv-Dev] Re: topology RFC (again)

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: jdorje@xxxxxxxxxxxx
Cc: freeciv-dev <freeciv-dev@xxxxxxxxxxx>
Subject: [Freeciv-Dev] Re: topology RFC (again)
From: "Ross W. Wetmore" <rwetmore@xxxxxxxxxxxx>
Date: Wed, 07 Nov 2001 20:38:01 -0500

Ok, let's go through the third example since you seem to be basing
your whole map system to fit this sort of odd GUI case. 

Before we really get into it, let's first think about the normal
wrapping maps and gui windows. If the normal map wraps at xsize
and we have a gui window larger than xsize we could keep filling
in tiles for as long as we want to extend the GUI window, but 
they would all be duplicates of those in the first xsize positions.
We don't do this for several reasons and thus normal GUI windows
are typically allowed to grow only up to the standard map limits.
The largest active portion of any GUI window is a standard map
sized rectangle.

Now you cleverly notice that if the GUI window is not aligned
with the wrapping directions, but is at say pi/4, then extending 
the GUI window in one dimension only can in some special cases
cover the entire map by projecting itself through multiple
virtual images in a sort of candy cane or barber pole effect.

This is quite an interesting representation, but is it useful for
game play in Freeciv? Do we want the whole system to be based on
contraints imposed by handing this model?

First, think about scrolling up the GUI window. Tiles will move off
the top part of the window, and appear one or more wrapped images
to one side. Put another way, adjacent tiles to the upper corner
might be 1/3 and 2/3 down the map along the top and bottom edge.
The current iso dislocation is bad enough, but adding multiple
loops around the candy cane to confuse it even more is not really
that great a feature to be basing your design model on.

Now, think about candy caning in general. Depending on the width
of your stripe, and the length to width dimensions of the underlying
standard map, you may find that you can exactly fit a single 
normalized set into a stretched rectangular stripe. However, most
of the time, stripes as they wrap around will start to overlap in
part previous several wrap lengths back in the window. You might
be able to keep on wrapping until you eventually include all tiles
and some different multiples of times. Or you may find that after
wrapping once or twice, you just duplicate the same stripe and
some tiles are never hit.

This means that the fundamental mechanics of deciding how many tiles 
fit in the GUI window and how many times some are being duplicated 
becomes a pretty hairy arithmetic exercise. If you follow the agreed
constraints not to duplicate tiles then you are going to have quite
a time.

It should be clear by this point that trying to wrap positions 
into arbitrary sized shapes is really a very foolish and expensive 
process. This is going about things ass-backwards.

You really want to first insure your shape is an N sized object.
This takes care of all the multiple image problems you have as a
simple constraint.

You next want to decide what shapes are reasonable for UI or memory
purposes, i.e. for doing pragmatic things. It might actually be
quite useful to have a linear vector for memory storage, though this
will put severe limitations on the length to width ratio, and probably
needs to be at least a double vector if you are wrapping objects
that need to have even dimensions. 

For UI, you really don't want the length to extend any more than the
maximum wrap dimension to minimize the odder characteristics of
candy caning. You really want to pick the "standard" form for the
UI that is an N-sized (typically rectangular because GUI windows
are rectangular, but possibly rotated) object whose dimensions are 
approximately the same as the natural map wrapping dimensions. The 
"unnormalizing" operation will take a map position and unwrap it 
into the N-shape offset from the map coordinates of window origin.
If your GUI window is not large enough to hold this full map image, 
you clip, and if it is too large you add black tile borders. Even
if you can squeeze more unique tiles into the black space in one
dimension, it is not necessary for the game and not advisable for
the above reasons. The user is better off stretching the other
direction to get a less confusing map representation, and not 
allowing stupid actions helps encourage this behaviour.

Finally, once you have the ability to work with native iso maps
that are rectangular in iso coordinates, as opposed to rotating a 
normal map into a display where the wrapping dimensions are at 
skewed angles to the GUI axes, you should never need to worry or
have any desire to use these things.

So, you need to ditch the _rect part of normalize_map_pos_rect() and 
get back to doing things in a nice clean layered fashion :-).


At 04:45 PM 01/11/02 -0500, Jason Dorje Short wrote:
>The third example showed that without giving dimensions to the set, it
>will sometimes fail to find to find a position that you are looking
>for.  Or, as I said before: "we don't just want a subset of a
>representative set, we want a different representative set".  Here's a
>simple example: suppose we have an overhead-view GUI.  It calls
>unnormalize_map_pos to wrap positions into a representative set with the
>following shape:
># # # # #
># # # # #
># # # # #
># # # # #
># # # # #
>But, suppose the GUI window has the following shape:
># # # # # # # #
># # # # # # # #
># # # # # # # #
>In this case, it is quite possible that an position along one of the
>bottom two rows of the representative set would actually have wrapped to
>be in one of the right three columns of the GUI window.  But if we only
>use clipping, we'll never know this.  The full example I gave showed a
>case where this happens using an iso-rectangular torus map; it can also
>happen using a flat-rectangular torus map and isometric view.

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