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

[Spell] How to calculate angle?

Status
Not open for further replies.
Level 21
Joined
Mar 29, 2020
Messages
1,237
hey,

this is probably a simple equation, but I have not touched geometry or trig for years, and haven't been able to find an explanation in terms I am familiar with enough to use in warcraft...

basically I need to solve for D:

angle.jpg


I want to be able to find the angle that is the middle of the angle from unit a to the other two units. using the angles from A to B and C is tricky bc I have found the angles in the game only go to 180, and I don't know where it crosses back over.

(my end goal is to make a unit run away from two other units, so I want to find the angle that will get him furthest away from both simultaneously.. so I will invert the result... )

how do I get angle D?

thanks!

EDIT: if I measure the distance between the 3 units to find the length of the triangle and use sine to find the objective angle, and the split that in half - that should be the objective angle I need, but how do I apply that to the unit's subjective angle (the on accessible in triggers)?

I could add or subtract that to the relative angle from a to b or from a to c, but how would i know if I need to add or subtract it?
 
Last edited:
Level 24
Joined
Jun 26, 2020
Messages
1,852
Ok after think about this, if I have the lines AB and AC and its inclination angles (the angle between the straight line the you formed with that points and the x-axis) b and c, that you get with the BJ function "AngleBetweenPoints", if you don't wanna use it calculate it manually:
  • To get the inclination angle b for example of AB you have (x1,y1) the point A and (x2,y2) the point B so: b=atan((y2-y1)/(x2-x1))
If I call d the inclination angle of AD (I think this is you wanna), the angles comply with b+180-c+2d=180 (obvious in degrees) for all values so the value of d would be: d=(360-b+c)/2

I'm not sure if I'm correct, pls let me know

Edit: no I'm wrong, the angle d is not the inclination angle of the line AD, is the angle between AD and AB or AC, to get the real inclination angle I think you have to add d the less value between b and c.
 
Last edited:
Level 21
Joined
Mar 29, 2020
Messages
1,237
to get the real inclination angle I think you have to add d the less value between b and c.

if line DA is on or near 0 of the x axis, wont adding the value of the angle go to 1.5 instead of 0.5? (instead of going to the middle it will go a wider angle by D amount). I don't get how not to have this problem when dealing with an unknown relation to the x angle which "AngleBetweenPoints" uses...
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,540
something like this?
  • get angle
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set VariableSet reals[0] = (Angle from (Position of Paladin 0003 <gen>) to (Position of Footman 0000 <gen>))
      • Set VariableSet reals[1] = (Angle from (Position of Paladin 0003 <gen>) to (Position of Footman 0001 <gen>))
      • Set VariableSet reals[2] = (reals[0] + reals[1])
      • Set VariableSet reals[3] = (reals[2] / 2.00)
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[0]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[1]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[2]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[3]))
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 100.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 200.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 300.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 400.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 500.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
not sure if it always works but it seemed to work fine for me.
 

Attachments

  • angle.w3m
    16.6 KB · Views: 12
Level 24
Joined
Jun 26, 2020
Messages
1,852
if line DA is on or near 0 of the x axis, wont adding the value of the angle go to 1.5 instead of 0.5? (instead of going to the middle it will go a wider angle by D amount). I don't get how not to have this problem when dealing with an unknown relation to the x angle which "AngleBetweenPoints" uses...
What?
something like this?
  • get angle
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set VariableSet reals[0] = (Angle from (Position of Paladin 0003 <gen>) to (Position of Footman 0000 <gen>))
      • Set VariableSet reals[1] = (Angle from (Position of Paladin 0003 <gen>) to (Position of Footman 0001 <gen>))
      • Set VariableSet reals[2] = (reals[0] + reals[1])
      • Set VariableSet reals[3] = (reals[2] / 2.00)
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[0]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[1]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[2]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[3]))
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 100.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 200.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 300.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 400.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 500.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
not sure if it always works but it seemed to work fine for me.
At the end, you can just got the avearage of both of the angles.
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
something like this?
  • get angle
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • Set VariableSet reals[0] = (Angle from (Position of Paladin 0003 <gen>) to (Position of Footman 0000 <gen>))
      • Set VariableSet reals[1] = (Angle from (Position of Paladin 0003 <gen>) to (Position of Footman 0001 <gen>))
      • Set VariableSet reals[2] = (reals[0] + reals[1])
      • Set VariableSet reals[3] = (reals[2] / 2.00)
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[0]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[1]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[2]))
      • Game - Display to (All players) for 30.00 seconds the text: (String(reals[3]))
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 100.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 200.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 300.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 400.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
      • Special Effect - Create a special effect at ((Position of Paladin 0003 <gen>) offset by 500.00 towards reals[3] degrees.) using Abilities\Spells\Undead\AbsorbMana\AbsorbManaBirthMissile.mdl
not sure if it always works but it seemed to work fine for me.

Haven't tried it yet but i assume this works... and of course it's way simpler than the ridiculous stuff I was trying...

I still don't get how it works though... when you do this :" (Angle from (Position of Paladin 0003 <gen>) to (Position of Footman 0000 <gen>))"
what angle is it measuring? the angle between this line and what? the x axis? bc I tried testing and printing this (the anggle between two units) while walking around another unit, and I'm prettty sure I always got positive values between 0 and 180. so I assume it crosses back over in the middle. If that is accurate I don't get how finding the avg between them helps: lets say angle D is the x axis - that should take the avg between lets say, 40 and 40 and give me back 40...

So I'm guessing it either prints the absolute value of the angle, or I just didn't notice the critical " - ". That makes everything make sense... thanks!
 
Level 2
Joined
Jan 10, 2021
Messages
10
vector u(xB-xA;yB-yA)=(a1;b1)
vector v(xC-xA;yC-yA)=(a2;b2)
Cos(CAB)=Cos(u,v)=(Abs(a1*a2+b1*b2))/(sqrt(a1^2+b1^2)*sqrt(a2^2+b2^2))
 
Status
Not open for further replies.
Top