Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2001:
[Freeciv-Dev] Re: directional system: more magic code cleanups
Home

[Freeciv-Dev] Re: directional system: more magic code cleanups

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: rf13@xxxxxxxxxxxxxxxxxxxxxx
Cc: "Ross W. Wetmore" <rwetmore@xxxxxxxxxxxx>, jdorje@xxxxxxxxxxxxxxxxxxxxx, freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: directional system: more magic code cleanups
From: "Ross W. Wetmore" <rwetmore@xxxxxxxxxxxx>
Date: Wed, 26 Sep 2001 23:19:30 -0400

At 10:23 AM 01/09/26 +0200, Raimar Falke wrote:
>On Wed, Sep 26, 2001 at 12:36:19AM -0400, Ross W. Wetmore wrote:
>> At 10:19 AM 01/09/25 +0200, Raimar Falke wrote:
>> >On Tue, Sep 25, 2001 at 03:11:26AM -0400, Ross W. Wetmore wrote:
>> >> At 09:12 AM 01/09/24 +0200, Raimar Falke wrote:
>> >Ok. However every piece of code which will get into cvs will be
>> >reformatted.
>> 
>> You obfuscated by you, right?
>
>Indent.

Your indent methods or technique have been commented on as not being 
quite like any others. And when they take code that is in conformance
with K&R 2 and do interesting things with it, the effort seems to have
other purposes.

Even if you are honestly trying to standardize the code, it is like
applying trig functions to a job without really understanding why they
don't always work. Automation is really not foolproof, especially if
used foolishly or misapplied.

Besides, you really should not touch patches except to fix major issues.
This means that sequences of patches can be rolled in and out smoothly
and the record of patches reflects what the submitter actually did, as
opposed to what was done to the code by someone with less knowledge and 
understanding. Following this rul would have saved a few extra bug fixes
that I know of.

There are a few issues like this that still need to be straightened out :-).

>> >Ok. From a test game:
>> >
>> >2: src=(43,4) dest=50,7)
>> >2:   orig=SE, jason=SE, ross=E, raimar=SE, raimar2=SE
>> >
>> >So we see that diff_x=7 diff_y=3. So we have a gradient of
>> >m=diff_y/diff_x=3/7.
>> >
>> >Now comes the tricky part where your error is: which gradient is the
>> >border between the SE part and the E part? I think your answer would
>> >be 0.5. Probably because m=1 divides the quadrant. And 1/2 would
>> >quarter the quadrant. THIS IS WRONG. The correct gradient is
>> >tan(pi/8)=0.4142... It is now no surprise that the gradient from above
>> >m=3/7=0.42857... is between 0.4142 and 0.5.
>> 
>> Raimar LOOK AT your numbers. You need to move 7 east and 3 south. It
>> should be clear as mud that the straightest direction looks like this
>> with the first move to the EAST.
>> 
>>  0 1 . . . . . .
>>  . . 2 3 . . . .
>>  . . . . 4 5 . .
>>  . . . . . . 6 7
>> 
>> Your trig functions are clearly a bit out of whack. Do you know why?
>
>
>Doing the example with pencil and paper:
>
>  0 . . . . . . .
>  . 1 2 3 . . . .
>  . . . . 4 5 . .
>  . . . . . . 6 7
>
>But why is your solution better? Because it is symmetrical?

Actually it is because it more closely follows the straightest direction
(which is what is drawn in the diagram). Both of our methods may do 
something quite different when applied iteratively in the general case. 

Aside:
  This is because they start from the iterated position and lose any  
  past recollection of partial moves into the next tile, i.e. after the 
  first move above, you should be 3/7 in y following the true straightest
  line, but iterating effectively resets you back to 0 in y, i.e you 
  start each subsequent step with a clean slate.

But the method is to return the "straightest direction at any given 
point", so with that strictest interpretation mine is doing exactly 
that except for the 50-50 case in which it always chooses the diagonal.

If you renamed the method almost_straightest_direction() yours would
then be equally valid.

This may illustrate a bit better how close the last two methods are.
Feel free to uncryptic mine along these lines if it stills seems so 
foreign, or conversely optimize yours by fixing a few of the tests and
code flow to eliminate redundancies and extra computations :-).

If you change my method to do something like this, you can get it
to duplicate yours (with just two more integer multiplies). I've 
expressed a couple of things in terms you used that may require 
outside tweaks if you try to apply this pseudo code fragment literally.

if (delta_y < delta_x) {
  if (delta_y * 65K < delta_x * (TAN_PI/8 * 65K))
    nn = !(xpos) ? 7 : 1;
} else {
  if (delta_x * 65K < delta_y * (TAN_PI/8 * 65K))
    nn = !(ypos) ? 3 : 5;
}

Aside: Note the outer 'if' is not strictly required, but it balances
       the load between x vs y so you only do one of the multiply
       tests in any particular case (+1 if vs ~3/4 x 2 '*').

This just determines which of the 4 cartesian directions you are 
"closest" to, with the fall throughs defaulting back to the diagonal
moves as in the original code (these are trivially recorded as
(!xpos)*4 + (!ypos)*2 in the earlier two compare sets). Note the
original code effectively has the TAN term set to "almost 0" though
it does this a little more verbosely in code paths.

The index positions here are arbitrary (and local to this routine)
in the same way xpos and ypos are. They are just a way to record the 
8 possible outcomes currently in the form ...

  6 3 2
  7 x 1
  4 5 0

Since this needs to be reported back in a particular direction
system the last step was to "translate" by returning tx[index], 
i.e. tx[0] = DIR8_SOUTHEAST, tx[1] = DIR8_EAST ...

>Yes it may be difficult to work with me but I have to understand
>it. But I feel I'm really close now. Have some patience.
>
>       Raimar
>
>-- 
> email: rf13@xxxxxxxxxxxxxxxxx
> Make a software that is foolproof, and only fools will want to use it.

Just for fun ... if you wanted to do the same thing for a hexagonal
6 coordinate direction system (for the moment not changing the 
cartesian x,y underlying coordinates), then you would do the same
"diagonal" tests to get 6, 2, 4, 0, drop one of the tests for "closest"
in x or y depending on how you oriented the hexagon and change the other
to be something close to PI/6 ratio. The dir returned would be 0-5 after
translation.

Thus just the tests/ratios and the final transformation would be 
affected (in ways that could be data-encoded).

What actual coordinates you would use for a "native" hexagon system
I'm not sure, but the changes to the code are probably just a simple
linear combination of the existing tests which can then be simplified.

I suspect there is a general form for this that directly computes the 
whatever-ants with less effort than looping over all to see which is
the closest match. If we do a few more it may become obvious, but for
now all that is needed is the current octant systems.

Cheers,
RossW
=====




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