Path: chuka.playstation.co.uk!news From: Christoph Luerig Newsgroups: scee.yaroze.programming.3d_graphics Subject: Re: Rotation, ApplyMatrix Query (fairly long) Date: Wed, 18 Mar 1998 10:32:11 +0100 Organization: PlayStation Net Yaroze (SCEE) Lines: 284 Message-ID: <350F949B.93337AA2@immd9.informatik.uni-erlangen.de> References: <34F3EFA2.4CD2@127.0.0.1> NNTP-Posting-Host: faui90.informatik.uni-erlangen.de Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="------------F1DD0B8A0025B822DD48F36E" X-Mailer: Mozilla 4.04C-SGI [en] (X11; I; IRIX 6.3 IP32) --------------F1DD0B8A0025B822DD48F36E Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hello Majik! I think the problem is the way you compute the distance between two points. The distance formula you use is the (or Norm mathematical speaking) is the so called L1-norm (d=abs(x)+abs(y)). But the norm, that reflects the geometric distance is the euclidian norm, which is defined as (d=fsqrt(x**2+y**2)). If you consider one of the values x or y to be zero, both formulas result in the same value, but if one of the values is not zero, and both values are greater than one, the L1-norm always results in a larger value than the euclidian norm. Take for instance x=1 and y=1, in the case the L1-norm results in 2, but the euclidian norm, which represents teh geometric distance (euclidian norm) is 1.414.. This means, that using the L1 norm distances, are overweighted at directions that are not pointed at a right angle. Christoph Luerig Majik wrote: > Hi, > While working on the Drone Tank routine for Combat3D I've noticed a > quirk, which may well be my sloppy code, but it looks like > a strangeness in RotMatrix, anyway take a butchers: > > some variables: > long dx, dz, tx, tz, mx, mz, td, td2, td3; > short angle; > MATRIX ltw; > GsCOORDINATE2 dir; > SVECTOR rot, hpl; > VECTOR hpw; > > where is the opponents tank? > tx = BTanks[op].coord2->coord.t[0]; > tz = BTanks[op].coord2->coord.t[2]; > > make a local copy of our tanks GsCOORDINATE2 struct > dir = *(BTanks[me].coord2); > > this bit seems to be needed to set which direction the tank is facing > I would have thought it would get it from the copy just done. > setVector(&rot, 0, tank->angle, 0); > RotMatrix(&rot, &(dir.coord)); > > Get the local to world transform matrix > GsGetLw(&dir, <w); > we consider an imaginary point in front of the tank > setVector(&hpl, 0, 0, TANK_BOUNDC << 4); > ApplyMatrix(<w, &hpl, &hpw); > // consider a point at the > // front of the tank > mx = dir.coord.t[0] + hpw.vx; > mz = dir.coord.t[2] + hpw.vz; > this is the postition of the point, after rotation. > > get a rough estimate of the distance > dx = tx - mx; > dz = tz - mz; > td = abs(dx) + abs(dz); // find the right angled distance > > decide whether we should turn clockwise, or anti-clockwise > angle = (tx < mx) ? -32 : 32; // which way to turn (if facing northish) > > if we're facing south, then we need to turn the opposite way > if(tank->angle > 1024 && tank->angle < 3072) > angle = tank->angle - angle; > else > angle += tank->angle; > > angle &= 4095; > > try out this new angle > setVector(&rot, 0, angle, 0); > RotMatrix(&rot, &(dir.coord)); > > GsGetLw(&dir, <w); > ApplyMatrix(<w, &hpl, &hpw); > > mx = dir.coord.t[0] + hpw.vx; > mz = dir.coord.t[2] + hpw.vz; // same point in > // front of the tank > get a rough estimate of the distance using this new rotated point > dx = tx - mx; > dz = tz - mz; > td2 = abs(dx) + abs(dz); // find the distance > > Now the algorythm works by seeing if this new rotation makes the drone > closer > to the opponent, so you're wondering whats the problem... > > If the angle is close to a right angle, 0, 1024, 2048, 3072... then the > results from > the ApplyMatrix seem inconsistent, take for example 3072, this gives an > x/z vector > of -75,0 say, the program decides to move -32, 3040, it tries this and > gets an x/z vector > of -75,0 the same. it then takes this turn (I have it hard coded to > always turn atm) and next > time round we get 3040 as the input angle, which this time gives it an > x/z vector of -75,-8 > different!, it then tries to turn +32, back to 3072, and this time it > gives it an x/z vector > of -75,-8... guess what happens next time round the loop* > > Now I know that the maths may still be a little screwy behind this > method > (it may be complete rubbish !) but it's still an interesting quirk? > > Or have I missed something? > > Majik. > > *answers on a postcard, sent to the waste paper bin :) > -- > -- Majik - Owner/Curator of the Sinclair Microcomputer Museum > -- Spod in a suitcase - ' Have Compiler, will travel ' > -- http://mudhole.spodnet.uk.com/~majik/ > -- --------------F1DD0B8A0025B822DD48F36E Content-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit Hello Majik!

I think the problem is the way you compute the distance between two points. The distance formula you use is the (or Norm mathematical speaking) is
the so called L1-norm (d=abs(x)+abs(y)).  But the norm, that reflects the geometric distance is the euclidian norm, which is defined as (d=fsqrt(x**2+y**2)). If you consider one of the values x or y to be zero, both formulas result in the same value, but if one of the values is not zero, and both values are greater than one, the L1-norm always results in a larger value than the euclidian norm. Take for instance x=1 and y=1, in the case the
L1-norm results in 2, but the euclidian norm, which represents teh geometric distance (euclidian norm) is 1.414..  This means, that using the L1 norm distances, are overweighted at directions that are not pointed at a right angle.
 

Christoph Luerig
 

Majik wrote:

Hi,
        While working on the Drone Tank routine for Combat3D I've noticed a
quirk, which may well be my sloppy code, but it looks like
a strangeness in RotMatrix, anyway take a butchers:

some variables:
        long dx, dz, tx, tz, mx, mz, td, td2, td3;
        short angle;
        MATRIX ltw;
        GsCOORDINATE2 dir;
        SVECTOR rot, hpl;
        VECTOR hpw;

where is the opponents tank?
        tx = BTanks[op].coord2->coord.t[0];
        tz = BTanks[op].coord2->coord.t[2];

make a local copy of our tanks GsCOORDINATE2 struct
        dir = *(BTanks[me].coord2);

this bit seems to be needed to set which direction the tank is facing
I would have thought it would get it from the copy just done.
        setVector(&rot, 0, tank->angle, 0);
        RotMatrix(&rot, &(dir.coord));

Get the local to world transform matrix
        GsGetLw(&dir, &ltw);
we consider an imaginary point in front of the tank
        setVector(&hpl, 0, 0, TANK_BOUNDC << 4);
        ApplyMatrix(&ltw, &hpl, &hpw);
                                        // consider a point at the
                                        // front of the tank
        mx = dir.coord.t[0] + hpw.vx;
        mz = dir.coord.t[2] + hpw.vz;
this is the postition of the point, after rotation.

get a rough estimate of the distance
        dx = tx - mx;
        dz = tz - mz;
        td = abs(dx) + abs(dz);         // find the right angled distance

decide whether we should turn clockwise, or anti-clockwise
        angle = (tx < mx) ? -32 : 32;   // which way to turn (if facing northish)

if we're facing south, then we need to turn the opposite way
        if(tank->angle > 1024 && tank->angle < 3072)
                angle = tank->angle - angle;
        else
                angle += tank->angle;

        angle &= 4095;

try out this new angle
        setVector(&rot, 0, angle, 0);
        RotMatrix(&rot, &(dir.coord));

        GsGetLw(&dir, &ltw);
        ApplyMatrix(&ltw, &hpl, &hpw);

        mx = dir.coord.t[0] + hpw.vx;
        mz = dir.coord.t[2] + hpw.vz;   // same point in
                                        // front of the tank
get a rough estimate of the distance using this new rotated point
        dx = tx - mx;
        dz = tz - mz;
        td2 = abs(dx) + abs(dz);        // find the distance

Now the algorythm works by seeing if this new rotation makes the drone
closer
to the opponent, so you're wondering whats the problem...

If the angle is close to a right angle, 0, 1024, 2048, 3072... then the
results from
the ApplyMatrix seem inconsistent, take for example 3072, this gives an
x/z vector
of -75,0 say, the program decides to move -32, 3040, it tries this and
gets an x/z vector
of -75,0 the same. it then takes this turn (I have it hard coded to
always turn atm) and next
time round we get 3040 as the input angle, which this time gives it an
x/z vector of -75,-8
different!, it then tries to turn +32, back to 3072, and this time it
gives it an x/z vector
of -75,-8... guess what happens next time round the loop*

Now I know that the maths may still be a little screwy behind this
method
(it may be complete rubbish !) but it's still an interesting quirk?

Or have I missed something?

Majik.

*answers on a postcard, sent to the waste paper bin :)
--
-- Majik - Owner/Curator of the Sinclair Microcomputer Museum
--      Spod in a suitcase - ' Have Compiler, will travel '
--              http://mudhole.spodnet.uk.com/~majik/
--

 

 

--------------F1DD0B8A0025B822DD48F36E--