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

[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: Tue, 30 Oct 2001 23:06:48 -0500

At 04:25 AM 01/10/30 -0500, Jason Dorje Short wrote:
>For those who don't want to read all of this, at least skip down to the
>part on unnormalize_map_pos and N(x,y) sets.

I've deleted most of the noise since it isn't really intelligible and
it isn't worth wasting time correcting all its mistakes. The real task 
is to get a valid practical model for Freeciv, not play math games :-).

>Now for a full explanation...
>
>You have labeled N(0, 0) to mean the "normal" set.  Currently this is
>the same as the regular set:

Let's just stick with normal for now and ignore this newfangled 
regular invention :-).

The twin problems are how to "normalize" coordinates to THE normal set. 
And how to reverse this process to find their value in some other set. 
While there are lots of arbitrary sets to the theoretical mind, for 
practical purposes we will always want one that gives us useful offsets 
from particular point, e.g. the point corresponding to the origin of a 
floating GUI wiondow for instance.

>Again N(0, 0) doesn't include the point (0, 0) so we have to come up
>with yet another definition:

Who cares if it contains the point 0,0? If this is what you are 
spending all your time fighting, or think that defeating this strawman
wins some other argument, you are arguing with yourself.

N(0,0) is a label that identifies a particular 2-D set. If it helps 
think of the two values as indices. The key concepts of one of these
sets are that all unique coordinates are represented exactly once
in such a set, and that equivalent coordinates are separated by a
multiple of some constant like map.xsize.

And the N(0,0) one is where memory is stored and accessed :-).

>So, in summary there are two reasons why the N(x,y)/unnormalize_map_pos
>system will not work:
>
>1.  It is impossible to uniquely and intelligently define a set N(x,y). 

I don't have any problems with this, I just pick one and ignore the rest :-)

>In the absence of a general definition, we have to choose specific (not
>particularly unique) definitions for each topology, and the calling code
>must be aware of them.

Actually choosing something that is useful, does sort of get the job 
done. And there is no reason why the calling code can't indicate 
some preferential form of the set by setting a "context" value if 
there are different choices available for different jobs.

>2.  The position returned by unnormalize_map_pos will lie within a set
>N(x0, y0).  This set will have a shape that is unique to the underlying
>topology, and has no special significance outside of it. 

Unless you ignore this theoretical conundrum, hold your nose, and just 
pick something that works.

> It will
>certainly not be useful to GUI code, which needs to wrap a map position
>into the GUI's "floating window" that hovers over the map.

Only if you stop short and let the overpowering impossiblity of this 
overwhelm you :-).

>Whew.

Okay, you want to get on with the job now?

>> If you want to choose the range in the relationship to be an arbitary
>> rectangle, then you certainly will have the chance to do everything
>> from missing it to hitting it multiple times. But this doesn't
>> correspond to any unnormalizing operation, or any other useful
>> operation that I can think of.
>
>To return to the normalize_map_pos_[rect|iso] functions:
>
>On the contrary, this is exactly the operation that is done now in the
>GUI code. 

No one says the current GUI code is particularly elegant. In fact fixing
it is the current problem, right?

Admit for a moment, this might be one of the problems.

> But this is a topology operation, and needs to be extracted
>from get_map_xy/get_canvas_xy and placed in the topology backend code. 

This I can certainly agree with.

>If you are unhappy with it, a collection of diff_map_pos topology
>operators can be used to do the same thing - the code is uglier but
>avoids the pitfalls that normalize_map_pos_rect has (by clearly defining
>where the new coordinate will be).

diff_map_pos() selects values in a range [-xsize/2:(xsize-1)/2] etc.

If *you* are happy with this range (which is at least one that defines
a unique N(*,*) set), then you should have no problem with unnormalize
that does the same except with a range [0:xsize-1], or any other full
N set definition that is appropriate to a "context".

If you want a smaller rectangular subset of this, as for a GUI window, 
then just apply a clip operation to the returned result (hopefully
though after you have transformed it to rectangular GUI coordinates). 

The real problem with normalize_map_pos_rect() is the arbitrary "rect"
that does not correspond to any N(*,*) set no matter how it is selected.
Plus the fact that it is defined in "rectangular" coordinates, and in
the general case, say for normalize_isomap_rect(), this is not the
native coordinate system. So the function is a confused hybrid.

The sample unnormalize works for a hardcoded default context that 
includes all current (and forseeable) rectangular coordinate cases
including the current bastard-iso flavours. When you produce something
that defines the true-iso coordinate system, we can do a corresponding
unnormalize_isomap_pos(), but probably choosing at least the default
"shape" of the N set to be rectangular as opposed to skewed by whatever
scheme you come up with for the coordinate numbering. 

The reason for the "default" is that practically, that is what one 
needs most of the time. If there are other needs, we can define the
appropriate additional contexts and/or algorithms as required.

Someday, maybe the impossibility of the general theoretical problem
will vanish and a real solution will even be found :-).

>jason

Cheers,
RossW
=====

unnormalize_map_pos(&un_x, &un_y, x0, y0) {

  /* unnormalize is only valid for real coordinates */
  if( !is_real_tile(*un_x, *un_y) )
    return FALSE;

  if( IS_WRAP_X ) {
    while( *un_x < x0 )
      *un_x += map.xsize;
    while( *un_x >= x0 + map.xsize )
      *un_x -= map.xsize;
  }
  *un_x = *un_x - x0;

  if( IS_WRAP_Y ) {
    while( *un_y < y0 )
      *un_y += map.ysize;
    while( *un_y >= y0 + map.ysize )
      *un_y -= map.ysize;
  }
  *un_y = *un_y - y0;

  return TRUE;
}




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