• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Calculating "backstab" angle

Status
Not open for further replies.
Level 9
Joined
Dec 12, 2007
Messages
489
Years ago, I've made a simple trigger that checks if an attacking unit is behind the attacked unit for bonus damage (typical Backstab case)

that time, I use angle comparison between facing angle of attacker and facing angle of attacked unit,

JASS:
local real attackerFace = GetUnitFacing(GetAttacker())
local real attackedFace = GetUnitFacing(GetTriggerUnit())
if attackedFace <= (attackerFace+dev) and attackedFace >= (attackerFace-dev) then
    ...
endif
with dev as allowed deviation angle


now, I've search a bit more information about this kind of calculation,
I've come up with result that the earlier angle comparison (method A) might not work as intended on specific angle case. which is why another method is proposed:

JASS:
function Angles_GetAngleDifference takes real a1, real a2 returns real
    local real x
       // The Modulo will get the co-terminal angle if the angle is less than -360 or greater than 360.
       set a1=ModuloReal(a1,360)
       set a2=ModuloReal(a2,360)
       // makes sure angle 1 is the smaller angle.  If it isn't it switches them.
       if a1>a2 then
           set x=a1
           set a1=a2
           set a2=x
       endif
       // Subtracts 360, to get the first negative co-terminal angle, this is then used in a comparison to check if the angle is greater than 180 (?)
       set x=a2-360
       if a2-a1 > a1-x then
           //  If it is, use the negative angle instead
           set a2=x
       endif
       //  Now, get the difference between the 2 angles.
       set x=a1-a2
       //  If the difference is negative, make it positive and return it.  If its positive, return it.
       if (x<0) then
           return -x
       endif
    return x
   endfunction
with input:
a1 as attacked unit facing angle and
a2 as attacker unit facing angle
if output x less than dev, then it's backstab



I simplify the GUI sample provided in this thread
JASS:
    function BackstabAngle takes unit u, unit v returns real
        local real angle1 = Atan2((GetUnitY(v)-GetUnitY(u)),(GetUnitX(v)-GetUnitX(u)))*bj_RADTODEG
        local real angle2 = GetUnitFacing(v)
       
        return Acos(Cos((angle1 - angle2)*bj_DEGTORAD))*bj_RADTODEG
    endfunction
with
u as attacking unit and
v as attacked unit
if output is less than deviation angle, then it's backstab


my question is, which method is more fail-proof?
timewise, method B was proposed at 2007 while Maker's (method C) was 2011,
is there any case/drawback with each method?
 
I would suggest method C (proposed by Maker) since it's less overhead than method B (Vexorian).

or,

JASS:
function IsUnitInBackstabAngle takes unit a, unit t, real max returns boolean
    local real t_facing = GetUnitFacing(t)
    local real a_angle = Atan2(GetUnitY(t) - GetUnitY(a), GetUnitX(t) - GetUnitX(a))*bj_RADTODEG
    if t_facing >= 180 then
        set t_facing = t_facing - 360
    endif
    return RAbsBJ(a_angle - t_facing) <= max
endfunction
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Method C is fastest in JASS. Despite trigonometric functions being slow to compute in reality, the reduced JASS virtual machine execution overhead gives much larger savings. The use of trigonometry can be confusing for those that are not mathematically gifted, especially since WC3 mixes degrees and radians.

Method B is the fastest and most understandable in reality. It is just slower than method C due to JASS lacking efficient Modulo support and having huge virtual machine overhead.

Method A style angle tests are known to fail or bug. I would not recommend it.

For performance sensitive applications method C is the only way to go. Otherwise using B or C is left up to personal style preferences.
 
Status
Not open for further replies.
Top