HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Side Position Detection

11-04-2008, 04:30 PM#1
Raydude
How would I be able to detect a unit within a 300 distance from an angle to another angle?
^ 45degrees
| /
| / x
| /
|/
| X
|\
| \ x
| \
| \
v 135degrees
For all the side detection I found on this site, are all "If attacked on the side then reduce/increase damage."(backstab/reduce side damage) None of them really detect if a unit were to enter a range of 300, order another unit to attack them (exp : turret of a ship, just wouldn't make sense to attack in a 360 degrees)
11-04-2008, 06:16 PM#2
Vexorian
Two angles' "distance" cannot be bigger than 180 degrees, man

Could you explain better what you want? For example try giving us sample input data and the result you want.
11-04-2008, 06:35 PM#3
Raydude
Eh I probably should've explained more, sorry. I drew a little weird diagram, the angle I want isn't 180, that'd be weird, it's from Current facing angle + 45 to Current facing angle + 135, the side of the unit. I drew that with slashes, the straight line was just indicating the unit
11-04-2008, 08:54 PM#4
tamisrah
-First you have to detect that a unit comes in range of your "turret"
-Then compare the angle between the "turret" and the triggering unit to the "turret"s facing angle
-If the difference is lower than your limit (45°) then all thats left is check whether the triggering unit is in front or behind your tower (see backstab detection)

The reason for the additional check is that angleBetweenPoints returns an angle between 0 and 180° as Vexorian already mentioned.
11-04-2008, 11:48 PM#5
Raydude
This is what I got so far to detect if Target[0] is at the side, but I have questions. Whenever I use that custom script, it always asks for a variable name, didn't I alrdy put it in, also when using the real, what numbers do I use to be "less than or equal to" and "greater than or equal to" so it'd be the sides, not tbe back of the unit?
Trigger:
Collapse Events
Time - Every 0.25 seconds of game time
Conditions
Collapse Actions
Set Target[0] = (Random unit from (Units within 300.00 of (Position of Carrier 0000 <gen>) matching ((((Matching unit) is alive) Equal to True) and ((Owner of (Matching unit)) Not equal to Player 1 (Red)))))
Custom script: set Real = Backstab_GetAngleDifference(GetUnitFacing(Carrier_0000()), GetUnitFacing(Target[0]()))
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Real Less than or equal to 60.00
Collapse Then - Actions
Floating Text - Create floating text that reads Works at (Position of Carrier 0000 <gen>) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
Floating Text - Change the lifespan of (Last created floating text) to 0.20 seconds
Else - Actions
P.S. I did put the math codes in the map
Hidden information:
function Backstab_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
11-05-2008, 03:23 PM#6
tamisrah
EDIT: Not exactly what I thought first but here you are:
Trigger:
ANGLE TEST
Collapse Actions
Set a1 = (Angle from p1 to p2)
Set a2 = (Facing of Akolyt 0000 <gen>)
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Condition
a2 Greater Than 180.00
Collapse Then - Actions
Set a2 = (a2 - 360.00)
Else - Actions
Custom script: set udg_a1 = GetAngleDifference(udg_a1,udg_a2)
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Condition
a1 Less Than Or Equal 45.00
Collapse Then - Actions
<<Put your Actions here>>
Else - Actions
11-06-2008, 12:27 AM#7
Anitarf
Try to use [jass] tags for your Jass code.

I think you need to explain what you need this for.
11-06-2008, 08:40 PM#8
Raydude
well, I'm trying to make a large ship with turrets/cannons that only shoots at units at port or portside that enter within 300 range and i can't get the measurements right
11-07-2008, 12:50 AM#9
PurplePoot
Try using the following for your angle measurement script: it's roughly 3 times faster than your function, though this is admittedly a pretty lame benchmark as I did it by freezing my game and counting (it ended up 2 for mine, 7 for yours, for several hundred thousand executions).

Acos(Cos(A-B)) where A, B, and the answer are all in radians.

So what you would do is detect:

Collapse JASS:
local unit u = //battleship
local unit u2 = //considered
local real a = Acos(Cos(Atan2(GetUnitY(u2)-GetUnitY(u),GetUnitX(u2)-GetUnitX(u)) - GetUnitFacing(u)*bj_DEGTORAD))
if a > bj_PI/4 and a < 3*bj_PI/4 then
    //go

If you want to go pure GUI,

Trigger:
Actions
-------- this leaks, too lazy to write in the fixes, you should know them --------
Set Angle = Acos(Cos(((Angle between (Position of (Battleship)) and (Position of (Considered))) - (Facing of (Battleship)))))
Collapse If (All Conditions are True) Then do (Then actions) Else do (Else actions)
Collapse If - Conditions
Angle > 45.00 Equal to True
Angle < 135.00 Equal to True
Collapse Then - Actions
-------- go nuts --------
11-07-2008, 03:14 PM#10
tamisrah
@PurplePoot:
You're version is only about twice as fast to my measurements but actually I'd like to ask you what your one actually does. What is the Acos(cos()) there for? In my opinion it should just nullify eachother but if I remove it the function returns false angles.
11-07-2008, 05:57 PM#11
Anitarf
That's a common mistake. You forget that the Acos function only returns values between 0 and pi, while the subtration of two angles between 0 and 2*pi could generate angles between -2*pi and 2*pi.

As a result, PurplePoot's function does not distinguish between targets on the left and targets on the right; he should be using Asin(Sin(...) instead.
11-07-2008, 10:57 PM#12
Raydude
Ah, thanks you all! It works and only targets the left side, if I changed the angle check to >225 and < 315 and it'll be right side. Now I'ma just change the unit that's acting as the cannon to stop bumping into the main unit. Btw, it works, but I have a feeling that there's a much easier check...maybe.

Untitled Trigger 003:
Collapse Events
Time - Every 0.50 seconds of game time
Conditions
Collapse Actions
Unit - Move CarrierShoot instantly to (Position of Carrier 0000 <gen>)
Set TargetUnit = NoTarget
Set TargetUnit = (Random unit from (Units within 300.00 of (Position of Carrier 0000 <gen>) matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of Player 1 (Red)) Equal to True))))
Game - Display to (All players) for 1.00 seconds the text: (String((Unit-type of TargetUnit)))
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
(TargetUnit is alive) Equal to True
(Owner of TargetUnit) Not equal to Player 1 (Red)
Collapse Then - Actions
Trigger - Run Untitled Trigger 001 <gen> (ignoring conditions)
Else - Actions
Untitled Trigger 001:
Events
Conditions
Collapse Actions
Set CarrierSpot = (Position of Carrier 0000 <gen>)
Set TargetSpot = (Position of TargetUnit)
Set Angle = (Asin((Sin(((Angle from CarrierSpot to TargetSpot) - (Facing of Carrier 0000 <gen>))))))
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
(Angle Greater than or equal to 45.00) and (Angle Less than or equal to 135.00)
Collapse Then - Actions
Unit - Order CarrierShoot to Attack TargetUnit
Collapse Else - Actions
Do nothing
Custom script: call RemoveLocation (udg_CarrierSpot)
Custom script: call RemoveLocation (udg_TargetSpot)
11-08-2008, 12:01 AM#13
PurplePoot
@Anitarf, I would personally just have another check completely for the right (especially since I assume it's a different cannon with a different cooldown). Perhaps a bad assumption, but meh.

EDIT: Ah, I see what you're getting it... Trust me to screw something like that up when being too lazy to just measure from facing + pi/2.

--

@tamisrah, in GUI or Jass? GUI hardly counts due to all the BJs.
11-08-2008, 11:04 AM#14
tamisrah
JASS with StopWatch natives, but I'm not totally confident with how to ensure precise measurements (just took the example and inserted both codes and measured the time to execute each one a thousand times)