News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Atan2, and some retarded problem

Started by LimoDriver, April 03, 2007, 03:57:07 AM

Previous topic - Next topic

LimoDriver

First things first... As the name states, I'm searching for code to Atan2.

I know I can write my own via masm32's FpuAtan proc and some conditional checking, I'm not too hot with FPU and if it's been done... Me happy :)

Second question is a really simple coding problem.

I have two angles, in radians - one is an "old" angle, and one is a "new" one.
I'm trying to approach this "new" angle with my "old" one, by a certian "approach" amount.

For example:

approach angle = 0.1f
old angle = 1.0f
new angle = 2.0f

the resulting old angle will be old angle + approach angle = 1.1f

now if the situation is reverse:

approach angle = 0.1f
old angle = 2.0f
new angle = 1.0f

now the old angle is 1.9f

The tricky part is when you realize that radians actually wrap around, so for instance:

approach angle = 0.1f
old angle = 0.5f
new angle = 6.0f

now the old angle should be 0.4f!

The problem itself is amazingly simple, but I feel like a complete retard trying to solve it...

This is the best I could come up with (posted in C for better understanding):


; This will fix the wrap-around:

while( abs( oldAngle - newAngle - 2 * PI ) < abs( oldAngle - newAngle ) ) oldAngle -= 2 * PI;
while( abs( oldAngle - newAngle + 2 * PI ) < abs( oldAngle - newAngle ) ) oldAngle += 2 * PI;

And then decide weather to add or substract the "approach angle".


If there is anyone with an idea, or with some suggestions, thanx in advance!

LimoDriver

Well, I think I'm getting the hang of this "fpatan" thing.
I've just copy pasted code from the FpuArctan source and replaced the "fld1" before "fpatan" with my "fld xx" ...

Now that that has been settled... I need ideas for the angle thingymaboob :)

zooba

I believe FPREM might be what you're after (modulus). Though I have never used it before, so you may want to speak to someone who has.

Cheers,

Zooba :U

raymond

zooba is right if one (or both) of your angles may exceed 2*PI. You must then reduce such an angle to less than 2*PI and using the fprem instruction is probably the best way to go.

Then, in order to determine in which direction you should approach, you need two "stacked comparisons":
IF "new" > "old"
   IF "new"-"old" < PI, "approach" = +1, ELSE "approach" = -1
ELSE
   IF "old"-"new" < PI, "approach" = -1, ELSE "approach" = +1


Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

Merrick

I know that the goal here (usually) is reduced CPU cycles, but I think the purest approach here is to convert the angles to vectors (2-vectors in this case) and to use the result of the cross product to determine direction. It's slower (but probably not too much if you're clever) and it has the added benefits that you don't care about factors of 2*pi and when LimoDriver is ready to take this up to 3D it will work and the other method really won't - well, not without a ridiculously large conditional structure. A little bit of a guess there...

LimoDriver

Thank you guys for such excellent suggestions.

zooba: I'm sure FPREM will come in handy, any day now

Raymond: although your code is superb, in every way, I have replaced the "fixed approach angle" with a new & fresh approach routine:


Old_angle = ( Old_angle * ( APPROACH_FACTOR - 1 ) + New_angle ) / APPROACH_FACTOR;


This will work regardless of weather the old angle is higher or lower then the new angle, and the best part is, that it will rotate my vector faster if the difference between the angles is bigger.
Since the APPROACH_FACTOR is a constant, this is pretty fast, too.

Merrick: it's always interesting to hear about a new method (new to me, at least). I'll try to work it out by myself before I return here crying. I think I can use the above mentioned new approach method with this "cross product" you speak of.

Cross product. Now, didn't I hear that in college somewhere ... <blows dust off his linear algebra workbook> :green

Ratch

LimoDriver,

     You can take this method or leave it.   You can "unwind" an angle real easy by just by masking the low order bits with this method.  In any case, the links are an interesting read.  Ratch


http://www.bmath.net/old/bmath/point.htm
http://www.masm32.com/board/index.php?topic=4765.0
http://www.asmcommunity.net/board/index.php?PHPSESSID=fb22cb3e35db45a0b462e32cde70fa6b&topic=21430.15

Merrick

LimoDriver,

If you do diev into linear algebra you're hooked. Your next (and final) step is quaternions...
Oh, and I forgot, if you REALLY want speed consider switching from angles represented in floating point as radians, etc. to binary representation as bitians.