[Freeciv-Dev] Re: topology RFC (again)
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
"Ross W. Wetmore" wrote:
> Some pseudo code examples to help explain key points once again.
> i.e. the arithmetic to do isometric (un)normalizations :-?
> At 04:45 PM 01/11/02 -0500, Jason Dorje Short wrote:
> >"Ross W. Wetmore" wrote:
> >> You may have to be clever to figure out just how you need to represent
> >> this wrapping or unwrapping algorithm. It is actually the same thing.
> >> If you feed in (0,0) for (x0,y0) for the rectangular case this should
> >> be clear, as it reduces cleanly to the simple normalize we have become
> >> accustomed to. When you work out the (un)normalize_iso_pos() they
> >> should have similar relationships that you can use to check.
> >No. unnormalize_map_pos(&x, &y, 0, 0) is not the same thing as
> >normalize_map_pos(0, 0). Normalize map_pos wraps (x, y) into the normal
> >set, which need not correspond to any particular representative set that
> >unnormalize_map_pos wraps into.
> Jason, THE normal set N(0,0) is something one designates in the manner
> needed. Once one has defined it, say to reference real memory in some
> appropriate manner, this is what normalize_map_pos() is written to
> return. unnormalize_map_pos() given the appropriate offset values will
> clearly return the offsets in this set if one chooses.
So you are saying normalize_map_pos(&x, &y) is or is not the equivalent
of unnormalize_map_pos(&x, &y, 0, 0)? If the latter, I agree. If the
former, then you are wrong. Only in specialized cases (a
flat-rectangular topology _and_ a flat-rectangular mapview or an
iso-rectangular topology _and_ an iso-rectangular mapview) will that be
the case. When you compare the two, it makes me think you are confusing
these two concepts (topology and mapview), even though that may not
actually be the case.
> >Take a look at the normalize_map_pos_[iso|rect] from my "general
> >topology" patch. (Aside from the width/height parameters, these are the
> >equivalent of your unnormalize_map_pos function.) Although we're just
> >doing simple linear-algebra operations, the arithmetic is very, very
> >ugly. And the implementation isn't even correct (it doesn't fit the
> >"wrap-to-a-square" criteria specified above).
> Actually, it isn't. For one thing, you have replaced all the while's with
> if's, so your version won't work with anything not a wrap distance from
> your N(0,0) set.
No. At the top of the function we call normalize_map_pos(x,y). This
takes care of all multi-wrapping issues.
> We'll leave the iso problems till a later analysis. You
> can judge the degree of ugliness below for yourself.
> >So, you're right. To implement unnormalize_map_pos you will have to be
> >clever and very good at arithmetic.
> Ok, lets fix up the unnormalize function for iso keeping things in
> rectangular map coordinates. There is probably a condition on the
> wrapping vectors that they be orthogonal to use this algorithm.
> THE normalized set or N(0,0) is defined by the rectangle formed by
> the wrapping vectors (i.e. vector dimensions of the rectangle) at
> some offset of your choice. (map.ysize,0) conveniently keeps all
> positions of this normalized set at small positive position. Note,
> just because we used (0,0) for the simple rectangular N(0,0) doesn't
> restrict us to use some other origin when working with iso.
As an aside, can we please stop calling it N(0, 0)? There is no "other"
N, so lets just call it THE normal set N.
unnormalize_map_pos/normalize_map_pos_[iso|rect] look for a well-defined
representative set which I will call P (since R won't work :-( ); these
sets have no relationship to N (except by chance).
[end argument phase. enter constructive conversation phase.]
> Note as well, this still defines a very practical unnormalization that
> is useful for accessing memory or describing the full iso GUI in its
> standard form or any subset of this (after appropriate transformations).
> This is what the current rectangular GUI gives, so it is perfectly
> adequate for isometric play. It also guarantees tiles are only shown
> once. We'll deal with your odd GUI tastes in a later discussion.
The math you provide is very pretty. I like it a lot, and will speedily
use it in the next iteration of the general-topologies patch. I have
only a few concerns:
- This math will not cover all topologies, only linearly-wrapping ones.
So, although it's a great mathematical system to use for the topology
backend we should avoid using it outside of there. This information
should not be saved in the savegame or sent server->client, but should
be assembled in topology_init() and used internally by the topology.
- How will you account for the width/height limits placed on the
wrapping by normalize_map_pos_[iso|rect]? Do you still believe these
are unnecessary, or are they what you mean by "my odd GUI tastes"?
- Nit: your numbers for mapiso are off. map.xsize and map.ysize do not
correspond directly to the wrapping vectors. Rather, these should use
map.topology.usize/map.topology.vsize (or whatever you choose to call
them). usize/vsize can also be used to compute xsize/ysize, but are
definitely distinct from them.
- Second nit: struct topo should have fields uwrap and vwrap, not xwrap
Here's another idea: can you think of a way to easily extend this math
to be useful in a "filter" system where we take some of the positions
within the "normal" set and define them as unreal? The problem in this
case is not the wrapping (which works the same), but the problem of
finding the nearest_normal_map_pos(). nearest_normal_map_pos is very
easy in the standard linear case (the math will be very similar to what
you've proposed for wrapping), but if we declare that some positions
within the "normal" region are unreal then it becomes very difficult
(see the ellipse topology in the general-topologies patch). This
problem would really go away if we dropped the concept of
nearest_normal_map_pos/nearest_real_tile. The only code that
legitimately needs it is GUI code that centers the map view (the
tilespec code could be handled without nearest_normal_map_pos, since
each unreal position will be guaranteed to be adjacent to a real
position). Can you think of any other way to handle this problem?
Finally, I'm getting really tired of these names:
unnormalize_map[iso|rect]_pos and normalize_map_pos_[iso|rect] are
equally misleading and inaccurate IMO. How about making a single
function find_representative_map_pos(&x, &y, context), where (x, y) is
the position to be wrapped and context defines the representative set we
want to wrap it into (i.e. x0, y0, width, height, iso, etc. as