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

Angle Between Points + Facing Angle

Status
Not open for further replies.
Level 10
Joined
Feb 22, 2008
Messages
619
Angle Between Points + Facing Angle = ?

  • Set Unit_Point = (Position of My_Unit)
  • Set Other_Units = (Units within 600.00 of Unit_Point)
  • Unit Group - Pick every unit in Other Units and do (Actions)
    • Loop - Actions
      • Set My_Variable = ?
I'm trying to complete the hypothetical trigger above, but my brain turns to jelly when I try to create a trigger that will set My_Variable to a value representative of where Picked Unit is relative to Unit_Point and what direction My_Unit is facing.
I'd like it to have the following effect:
  • Set My_Variable to 0 if Picked Unit is directly ahead of My_Unit
  • Set My_Variable to 90 if Picked Unit is a 90° turn to the left of My_Unit
  • Set My_Variable to 180 if Picked Unit is directly behind My_Unit
  • Set My_Variable to 270 if Picked Unit is a 90° turn to the right of My_Unit
I've read some threads on the general subject but still don't have a strong enough understanding to make progress, so I came here for your help!

EDIT:
Unit A is the unit I care more about. I pay attention to his Facing Angle. I want to know Unit B's values relative to Unit A.
How many degrees does Unit A have to turn to the left to be facing Unit B (no negative values allowed)? That's what I'd like My_Variable to be.
 
Last edited:
Level 37
Joined
Jul 22, 2015
Messages
3,485
If I understand you correctly, this should work.

Save the location of both units.
  • Set TempUnit1_Loc = (Position of TempUnit1)
  • Set TempUnit2_Loc = (Position of TempUnit2)
Then use the Math - Angle Between Points function.
  • Set TempAngle = (Angle from TempUnitLoc1 to TempUnitLoc2)
I apologize if this doesn't solve your issue. I'm a little confused with what your desired output is.
 
Level 10
Joined
Feb 22, 2008
Messages
619
If I understand you correctly, this should work.

Save the location of both units.
  • Set TempUnit1_Loc = (Position of TempUnit1)
  • Set TempUnit2_Loc = (Position of TempUnit2)
Then use the Math - Angle Between Points function.
  • Set TempAngle = (Angle from TempUnitLoc1 to TempUnitLoc2)
I apologize if this doesn't solve your issue. I'm a little confused with what your desired output is.
That's about half of it.

I made an image to help demonstrate what I mean.
bad_picture.jpg
Let's imagine the Yellow footman in the center of the image is My_Unit.
At the moment My_Unit is facing South, so the 0 is on the bottom.
The green numbers above the heads of the other footmen are (rough estimates of) what I'd like My_Variable to be set to when that unit is the Picked Unit.
A unit directly to the left of My_Unit should return 90, regardless of the direction My_Unit is facing
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
That's about half of it.

I made an image to help demonstrate what I mean.
bad_picture.jpg
Let's imagine the Yellow footman in the center of the image is My_Unit.
At the moment My_Unit is facing South, so the 0 is on the bottom.
The green numbers above the heads of the other footmen are (rough estimates of) what I'd like My_Variable to be set to when that unit is the Picked Unit.
A unit directly to the left of My_Unit should return 90, regardless of the direction My_Unit is facing

Thank you for the image. So all you want to do is make all units within the area face the unit in the center?
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
I did the following:
  • Melee Initialization
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set angle1 = (360.00 - (Facing of Footman 0000 <gen>))
      • Set angle2 = (Angle from (Position of Footman 0000 <gen>) to (Position of Footman 0001 <gen>))
      • Game - Display to (All players) the text: (String((angle2 + angle1)))
      • Set angle1 = (360.00 - (Facing of Footman 0002 <gen>))
      • Set angle2 = (Angle from (Position of Footman 0002 <gen>) to (Position of Footman 0003 <gen>))
      • Game - Display to (All players) the text: (String((angle2 + angle1)))
Which prints
270 (south-west units)
180 (north-east units)

52d9b76e847da9b712aff5ad9f1a7c8d.jpg


edit: Now that I think about it, making two groups were unneeded. I just needed one unit to center around, not two.
 
Last edited:
Level 10
Joined
Feb 22, 2008
Messages
619
Thank you for the image. So all you want to do is make all units within the area face the unit in the center?
I don't want to actually change anything in the game, I just want My_Variable to be set to the right value. That value should be 0 when the check is performed on Unit A and Unit B with Unit B in front of where Unit A is facing. The value should be 45 if Unit A has to turn 45 degrees to the left to be looking directly at Unit B, and so on.
Basically, how many degrees does Unit A have to turn to the left to be facing Unit B (no negative values allowed)? That's what I'd like My_Variable to be.

I did the following:
  • Melee Initialization
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set angle1 = (360.00 - (Facing of Footman 0000 <gen>))
      • Set angle2 = (Angle from (Position of Footman 0000 <gen>) to (Position of Footman 0001 <gen>))
      • Game - Display to (All players) the text: (String((angle2 + angle1)))
Which prints
270 (south-west units)
180 (north-east units)
I tested your trigger. It's simpler than I thought it might need to be, and it works perfectly when the unit is facing directly West (I can tell that you know exactly what I'm looking for)

When the unit is turned to face directly East, the values returned are identical to those returned with the Angle From function (a -180 to 180 range). When the unit is turned to face North, values can be returned that are greater than 360. No matter what direction the unit is facing, some of the values returned will be desired, but usually not all.
The map I made to test your trigger has one footman (facing West by default) and some peasants. When <escape> is pressed it will return Angle 1, Angle 2 and their sum for the location of the unit currently selected.

So far what I've come up with is this, which will convert the negative values from the Angle From function to their respective places on a 360 degree circle.
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • angle2 Less than 0.00
    • Then - Actions
      • Set angle2 = (angle2 + 360.00)
    • Else - Actions
With that, we can manage two more similar values
-Angle Between Points from 0 to 360 (as opposed to -180 to 180)
-Facing angle from 0 to 360

The question is, how to use these values properly...

EDIT:
The following trigger has the desired effect, but I can't help but feel that there's a less messy way to do it (without using If/Then conditions). It's a trigger that will be looping a lot, so I'd like it to be as clean as possible.

Is there a better way to write this? (Ignoring leaks and such) - Perhaps I should bring that question to Triggers & Scripts now that it's much more formulated...
  • Events
    • Player - Player 1 (Red) skips a cinematic sequence
  • Conditions
  • Actions
    • Set unit1 = Footman 0000 <gen>
    • Set point1 = (Position of unit1)
    • Set unit2 = (Random unit from (Units currently selected by Player 1 (Red)))
    • Set point2 = (Position of unit2)
    • Set angle1 = (Facing of Footman 0000 <gen>)
    • Set angle2 = (Angle from (Position of Footman 0000 <gen>) to point2)
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • angle2 Less than 0.00
      • Then - Actions
        • Set angle2 = (angle2 + 360.00)
      • Else - Actions
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
      • If - Conditions
        • (angle2 - angle1) Less than 0.00
      • Then - Actions
        • Set my_variable = ((angle2 - angle1) + 360.00)
      • Else - Actions
        • Set my_variable = (angle2 - angle1)
    • Game - Display to (All players) the text: (String(angle1))
    • Game - Display to (All players) the text: (String(angle2))
    • Game - Display to (All players) the text: (String(my_variable))
This is a download link to the same map as before but with the above trigger within.
 
Last edited:
Level 10
Joined
Feb 22, 2008
Messages
619
It works fine in the test map you sent me?

I tested right,left,up,down all return correct value to me.

Unit is facing to the left (west).
Peasant infront of him = 3 (0)
Peasant left of him = 89 (90)
Peasant right of him = 271 (270)
Peasant behind him = 174(180)
You mean the first one?
In the first one, it'll return all of the correct values as long as the footman is facing West. Any other direction and it won't be 100% accurate.
The second map returns all of the correct values, but I'd like to do it without the If/Then conditions if possible
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
Oh right if the angle becomes negative, was it? I don't think there is a workaround with the simple math I am using. You'll likely need some other formula to never get a negative value.

I only think you need one "if" though. If angle + angle 2 < 0 then add 360 to either angle or angle2, the rest is not needed afaik.
 
Status
Not open for further replies.
Top