• 🏆 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!

Difference between angles - easy solution

Status
Not open for further replies.
Level 37
Joined
Mar 6, 2006
Messages
9,240
I've seen this problem many times. People ask how they can get the difference between two angles.

I've not seen an easy solution. Maybe my search abilities just fail :) Well, here's one.

It works for any angle, for example the difference between 350 and 10 returns 20, and difference between -170 and 170 returns 20.

You can easily modify it for different purposes, like detecting whether a unit is facing another, withing certain tolerance:

Angles_3443.jpg


The key is this:
JASS:
Acos( Cos(r1) * Cos(r2) + Sin(r1) * Sin(r2) ) * bj_RADTODEG

Below are examples how to use it.

JASS:
library Attack initializer InitTrig_Attack_JASS

    
    private function getAngleDifference takes real r1 , real r2 returns real
        return Acos( Cos(r1) * Cos(r2) + Sin(r1) * Sin(r2) ) * bj_RADTODEG
    endfunction

    
    private function Action takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local unit v = GetOrderTargetUnit()
        local real r1 = GetUnitX(u)
        local real r2 = GetUnitY(u)
        local real r3 = GetUnitX(v)
        local real r4 = GetUnitY(v)
        // Angle from "caster" to target
        local real r5  = Atan2( r4 - r2 , r3 - r1 )
        local real r6 = GetUnitFacing(u) * bj_DEGTORAD
        local real r7
        
        set r7 = getAngleDifference( r5 , r6 )
        
        call DisplayTextToPlayer( Player(0) , 0 , 0 , "(JASS) The angle difference between " + R2S(bj_RADTODEG * r5) + " and " + R2S(bj_RADTODEG * r6) + " is " + R2S(r7) + " degrees." )

        set u = null
        set v = null
        
    endfunction


    private function InitTrig_Attack_JASS takes nothing returns nothing
        local trigger t1 = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ( t1, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
        call TriggerAddAction( t1, function Action )
        set t1 = null
        
    endfunction
    
endlibrary


  • Attack GUI
    • Events
      • Unit - A unit Is issued an order targeting an object
    • Conditions
    • Actions
      • -------- -------------------------------------------------- --------
      • -------- Set unit variables --------
      • -------- -------------------------------------------------- --------
      • Set u1 = (Triggering unit)
      • Set u2 = (Target unit of issued order)
      • -------- -------------------------------------------------- --------
      • -------- Set location variables --------
      • -------- -------------------------------------------------- --------
      • Set p1 = (Position of u1)
      • Set p2 = (Position of u2)
      • -------- -------------------------------------------------- --------
      • -------- Get angle from "caster" to target --------
      • -------- -------------------------------------------------- --------
      • Set r1 = (Angle from p1 to p2)
      • -------- -------------------------------------------------- --------
      • -------- Get caster facing --------
      • -------- -------------------------------------------------- --------
      • Set r2 = (Facing of u1)
      • -------- -------------------------------------------------- --------
      • -------- Get angle difference --------
      • -------- -------------------------------------------------- --------
      • Set r3 = (Acos((((Cos(r1)) x (Cos(r2))) + ((Sin(r1)) x (Sin(r2))))))
      • -------- -------------------------------------------------- --------
      • -------- Print the angle --------
      • -------- -------------------------------------------------- --------
      • Game - Display to Player Group - Player 1 (Red) for 10.00 seconds the text: (Difference between + ((String(r1)) + ( and + ((String(r2)) + ( is + ((String(r3)) + degrees.))))))
      • -------- -------------------------------------------------- --------
      • -------- Clear leaks --------
      • -------- -------------------------------------------------- --------
      • Custom script: call RemoveLocation(udg_p1)
      • Custom script: call RemoveLocation(udg_p2)
      • -------- -------------------------------------------------- --------


If there are bugs, let me know. I'll be using this in a map of my own.

Note that angles > 180 are converted to -180...0 range, so the displayed text may lead you wrong, the difference should be correct.
 

Attachments

  • Angle_Difference.w3x
    18.1 KB · Views: 56
Last edited:
Personally, I use that :
JASS:
function AngleSubtract takes real angle1,real angle2 returns real
    local real Angle=RAbsBJ(angle1 - angle2)
    if (Angle>=180) then
        return 360 - Angle
    endif
    return Angle
endfunction

It takes degrees while yours takes radians and I guess it is faster.
I compared the results between your method and mine and it's equal until the third decimal. It may be the deg/rad conversion, though.
 
Level 14
Joined
Nov 18, 2007
Messages
1,084
Sorry for the bump, but I think this post is worth the necro.
JASS:
function GetAngleDifference takes real ang1, real ang2 returns real
    return Acos(Cos(ang1-ang2)) // I'll just leave it in radians.
endfunction
This is just a simplified version of Maker's method. (Yay for composite arguments!)
I don't think there are any downsides with this method though I haven't tested it too much.
 
Status
Not open for further replies.
Top