• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

Angle Calculations

Status
Not open for further replies.
Level 13
Joined
Mar 16, 2008
Messages
941
Okay, I'm giving up now :D

I realy like maths, but I can't think of these angle-calculations.
Just can't think right with the warcraft angle stuff.

I got two angles.
One is the actual movement direction of a missle.
The second one is the angle between the missle and a unit.

Let's for example say, I want the missle to change the direction
by 10% towards the unit.
I wanted to divide the angles, depending one which one is bigger:
JASS:
if angle > .oldangle then
    set .oldangle = .oldangle+(angle-oldangle)*ACCURACY
else
    set .oldangle = .oldangle-(oldangle-angle)*ACCURACY
endif
.oldangle is the movement of the missle,
angle the one between the two units.
This example applies the angle difference by ACCURACY%,
at least I hope that this is right.

Like you might know, this fails as soon as for example
angle is 10 and .oldangle is 320.
Angle would be bigger, but the value of .oldangle is.

I know that many people know how to correctly calculate
this, but I can't ^^'

Can anyone help me? :)

Greets, Justify
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
You haven't really told us anything other than you tried this code and it didn't work. What do you want the outcome to be?

Say you have two angles, a1 is the angle of movement, and a2 is the angle between the two units. How exactly do you want a2 to affect a1?
 
Level 13
Joined
Mar 16, 2008
Messages
941
Like you might know, this fails as soon as for example
angle is 10 and .oldangle is 320.
Angle would be bigger, but the value of .oldangle is.
How to fix this bug, I thought it was obvious.
Like I said I want to change .oldangle slowly to match
angle, using steps with ACCURACY.
This means I need the lowest difference of the angles
(there are always two: angle-.origangle and .origangle-angle).
However, the difference of an angle of 10 and an angle of
320 is with pure math 310, thats like the trigger works.
The lowest possible real angle difference with the
warcraft angles is 50.
I want to know how to fix this part of code so that
even angle differences like 10 to 320 are recognized correctly.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Why do you constantly press "Enter" when you are typing it makes your thoughts so unorganized.

Justify said:
using steps with ACCURACY.

What the hell do you mean by this? I asked you to explain yourself and you just typed the same thing in different words.

Justify said:
However, the difference of an angle of 10 and an angle of
320 is with pure math 310, thats like the trigger works.

What do you mean with "pure math"? With "pure math" you use radians, not degrees.

Justify said:
The lowest possible real angle difference with the
warcraft angles is 50.

Don't know what you mean by the lowest angle difference in WarCraft... makes no sense to me because there is no "lowest possible" anything when dealing with angles.

Justify said:
I want to know how to fix this part of code so that
even angle differences like 10 to 320 are recognized correctly.

So you want to make your function to work properly?

Okay well I'll see what I can do but to be honest you really need to organize your thoughts better I'm having a really hard time trying to figure out what you're thinking here. A good start would be to stop hitting "Enter" in the middle of a sentence.

Using double-enters when you're done a paragraph of writing keeps separate ideas, separate.

Justify said:
This means I need the lowest difference of the angles
(there are always two: angle-.origangle and .origangle-angle).

No, not the lowest difference, just the difference. Its almost as if you're trying too hard to explain yourself lol.

In WarCraft III the function Atan2 returns negative values when the angle (in degrees) is above 180. This means from 0° to 180° the angles are represented normally. Once angles exceed 180°, they start increasing from -180° to -0°.

JASS:
function FindTrueAngle takes real a returns real
    if (a < 0) then
        set a = 180 + (180+a)
        // When 'a' is -160° (example), we want this function to return +200°. (180 + (180 + (-160)) = 180 + 20 = 200)
    endif
    return a
endfunction
 
Last edited:
I'm currently using this code to make it.
AdjustAngleRad( angle ) returns the equivalent angle between 0 and 2*PI (in radians, of course).

JASS:
function AdjustAngleRad takes real a returns real
    loop
        exitwhen a >= 0
        set a = a + 2*bj_PI
    endloop
    loop
        exitwhen a <= 2*bj_PI
        set a = a - 2*bj_PI
    endloop
endfunction

JASS:
set Angle = AdjustAngleRad( <Angle From Missile To Target> )
set RealA = AdjustAngleRad( Angle - <Missile Angle> )
set RealB = AdjustAngleRad( <Missile Angle> - Angle )
if RealA < RealB then
    set Step = (RMinBJ( RealA, <Max Step> ))
else
    set Step = (-RMinBJ( RealB, <MaxStep> ))
endif

I don't remember clearly the math I used to come up with this, but it has worked so far flawlessly...
I think the important part is to keep all angles (as well as angle differences) between 0 and 2*PI.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
It doesn't matter whether you use radians or not. The code I showed you will determine the "real" value of the angle on the interval of [0, 360]. Once you have the proper angles you can find the difference between them. You could do this one of two ways:

JASS:
if ( a[0] > a[1] ) then
    set dif = a[0] - a[1]
else
    set dif = a[1] - a[0]
endif

Or:

JASS:
set dif = a[0] - a[1]
if (dif < 0) then
    set dif = dif * -1
endif

Macelo Hossomi said:
I don't remember clearly the math I used to come up with this, but it has worked so far flawlessly...

Can't you quite easily just look at the math you used? In order to convert from degrees to radians you simply multiply by (Pi/180). The Atan2 function only returns values on the interval [ -Pi/2, +Pi/2 ], which means that you'll have to convert your value so that it lies on the interval [0, 2*Pi] or [0, 360]. In order to do this, you can read the code I posted in my previous post.

JASS:
function FindTrueRadians takes real a returns real
    if (a < 0) then
        set a = bj_PI + (bj_PI+a)
    endif
    return a
endfunction

This is the same thing if you wanted to use radians.
 
Level 18
Joined
Jan 21, 2006
Messages
2,552
Marcelo Hossomi said:
Why 180 + (180+a) ?

What do you mean? That is the correct math, that's why? If you're talking about it not being written as 360 + a is because I wanted to break it down for the reader. I don't actually use this function I just typed it up on the forum.

The loop isn't really necessary either, nothing in WarCraft III spits out exaggerated values like PI x 12 radians or -720 degrees. If you are getting these values in your calculations then your math is wrong.
 
Level 13
Joined
Mar 16, 2008
Messages
941
I don't know, I just don't like these wide texts, it looks wrong in my mind :D
I'll try to stop it ;)

Okay, for the last time, I try to explain what I want to achieve:
I got a missle which moves into the direction of my first angle.
If the missle recognizes a unit, I want it to travel into it's direction, but if I change the angle instantly to the new on, it looks like an edge, not fluent, you know what I mean?

So I thought that I'll just apply a percentage of the angle difference to my missle, so for example: The old traveling direction was PI, west, and the missle finds an unit located south of it, 1.5PI. Now the angle PI will slowly match 1.5PI, in steps like 1.1PI, 1.2PI...
So I take the lower difference of the angle (using the shortest path, anything else would look very stupid) and add it at 10% to the first angle.
In this example: angle = PI+(1.5PI-PI)*0.1

Your code, Berbanog, works fine if you try it for example with 180 degrees and 270.
But what if I have angles of 350 and 10?
JASS:
if ( 350 > 10  ) then
    set dif = 350 - 10    //340 (need to substract 360)
else
    set dif = 10 - 350    //-340 (need to apply +360)
endif
The shortest difference of the angles 350 and 10 is 20!
Due to this example with your formula, I found a function to get it:
JASS:
    private function GetAngleDifference takes real from, real to returns real
        local real dist = to-from
        
        if dist > bj_PI then
            set dist = dist-2*bj_PI
        elseif dist < -bj_PI then
            set dist = dist+2*bj_PI
        endif
    
        return dist
    endfunction

Sorry that I harmed your patience, and thanks to the two of you ;)
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
I'm currently using this code to make it.
AdjustAngleRad( angle ) returns the equivalent angle between 0 and 2*PI (in radians, of course).

JASS:
function AdjustAngleRad takes real a returns real
    loop
        exitwhen a >= 0
        set a = a + 2*bj_PI
    endloop
    loop
        exitwhen a <= 2*bj_PI
        set a = a - 2*bj_PI
    endloop
endfunction

JASS:
ModuloReal(dividend, divisor)
// calcs:
ModuloReal(3*bj_PI,2*bj_PI)          = bj_PI
ModuloReal(12*bj_PI,2*bj_PI)         = 0
ModuloReal(-bj_PI,2*bj_PI)           = bj_PI
ModuloReal(-3.5*bj_PI,2*bj_PI)       = 1.5*bj_PI
// enough examples?
 
Last edited by a moderator:
Level 18
Joined
Jan 21, 2006
Messages
2,552
Justify said:
Your code, Berbanog, works fine if you try it for example with 180 degrees and 270.
But what if I have angles of 350 and 10?
if ( 350 > 10 ) then
set dif = 350 - 10 //340 (need to substract 360)
else
set dif = 10 - 350 //-340 (need to apply +360)
endif
The shortest difference of the angles 350 and 10 is 20!
Due to this example with your formula, I found a function to get it:

Oh now I see what you mean, I don't know why that didn't even come to mind before.
 
The loop isn't really necessary either, nothing in WarCraft III spits out exaggerated values like PI x 12 radians or -720 degrees. If you are getting these values in your calculations then your math is wrong.

I have my reasons, angles in my map come from many strange places xD
Whatever, it really doesn't matter...

JASS:
ModuloReal(dividend, divisor)
// calcs:
ModuloReal(3*bj_PI,2*bj_PI)          = bj_PI
ModuloReal(12*bj_PI,2*bj_PI)         = 0
ModuloReal(-bj_PI,2*bj_PI)           = bj_PI
ModuloReal(-3.5*bj_PI,2*bj_PI)       = 1.5*bj_PI
// enough examples?

Yes, that's enough /jumpsthroughwindow
I deserve to be killed. Twice.
 
Last edited by a moderator:
Status
Not open for further replies.
Top