Getting Units Behind

Any simple and efficient alternative other then using LineSegments to detect whether units are behind another unit?

For example

Unit Caster :banghead: into Unit Target in his path. Something like a SetUnitPosition thing when it knocks into another unit while moving.
 

roXplosive

New Member
Well I refrained from posting here but how I see the matter is the folowing : I consider untis behind a unit the units in a rectangle of length y and width x situated behind the target unit and rotated with an angle equal with the angle the attacker and defender make . (maybe I didn't make myself clear but hopefully this will settle the matter :

[img=http://img190.imageshack.us/img190/1004/units.th.png]


And saya trigger action

JASS:

function Actions takes nothing returns nothing
//if event fires on damage use GetEventDamageSource()
local real attX=GetUnitX(GetAttacker())
local real attY=GetUnitY(GetAttacker())
local real defX=GetUnitX(GetTriggerUnit())
local real defY=GetUnitY(GetTriggerUnit())
local real X=250 //units 250 ??? behind the target
local real Y=75  // units 75 distance to the left/right of the target
local real tgtsize=25 //consider target size around 50 for simplicity so here we get units behind it
//now our desired rectangle will be rotated and so we need 4 points for (it)
local real x1
local real y1
local real angle1
local real x2
local real y2
local real angle2
local real dist_close
local real x3
local real y3
local real angle3
local real x4
local real y4
local real angle4
local real dist_far
local real xc //center of rectangle X
local real yc //center of rectangle Y
local real sign1
local real sign2
local real sign3
local real sign4
//signs used for apartenence inequations
local real dist=SquareRoot((attX-defX)*(attX-defX)-(attY-defY)*(attY-defY))+tgtsize
local real angle
local group g1
local group g2
local unit un
local real unX
local real unY

set x1=attX+dist
set y1=attY-Y
set angle1=Atan((y1-attY)/(x1-attX))
set x2=attX+dist
set y2=attY+Y
set angle2=Atan((y2-attY)/(x2-attX)) //or -angle1 but it's more readable this way
set dist_close=SquareRoot((x1-attX)*(x1-attX)+(y1-attY)*(y1-attY))
set x3=attX+dist+X
set y3=attY-Y
set angle3=Atan((y3-attY)/(x3-attX))
set x4=attX+dist+X
set y4=attY+Y
set angle4=Atan((y4-attY)/(x4-attX))
set dist_far=SquareRoot((x3-attX)*(x3-attX)+(y3-attY)*(y3-attY))

if attX-defX<0 then //if attacker is to the left of defender then we are in quadrant 1,4
  set angle=Atan((defY-attY)/(defX-attX))
else
 set angle= bj_PI+Atan((defY-attY)/(defX-attX))
endif

//rotating the new rectangle
set x1=attX+dist_close*Cos(angle1+angle)
set y1=attY+dist_close*Sin(angle1+angle)
set x2=attX+dist_close*Cos(angle2+angle)
set y2=attY+dist_close*Sin(angle2+angle)
set x3=attX+dist_far*Cos(angle3+angle)
set y3=attY+dist_far*Sin(angle3+angle)
set x4=attX+dist_far*Cos(angle4+angle)
set y4=attY+dist_far*Sin(angle4+angle)

//obtaining the rectangle's center
set xc=(x1+x2+x3+x4)/4
set yc=(y1+y2+y3+y4)/4

//obtaining the inequation signs
set sign1=RsignBJ((yc-y1)*(x2-x1)-(xc-x1)*(y2-y1))
set sign2=RsignBJ((yc-y2)*(x3-x2)-(xc-x2)*(y3-y2))
set sign3=RsignBJ((yc-y3)*(x4-x3)-(xc-x3)*(y4-y3))
set sign4=RsignBJ((yc-y4)*(x1-x4)-(xc-x4)*(y1-y4))

call GroupEnumUnitsInRange(g1,defX,defY,dist_far,Filter(function True)) //make a function that returns true because null here leaks
loop
  set un=FirstOfGroup(g1)
  exitwhen un==null
  set unX=GetUnitX(un)
  set unY=GetUnitY(un)
  if sign1*((unY-y1)*(x2-x1)-(unX-x1)*(y2-y1))>=0 and sign2*((unY-y2)*(x3-x2)-(unX-x2)*(y3-y2))>=0 and sign3*((unY-y3)*(x4-x3)-(unX-x3)*(y4-y3)) and sign4*((unY-y4)*(x1-x4)-(unX-x4)*(y1-y4)) then
  call GroupAddUnit(g2,un)
  endif
  call GroupRemoveUnit(g1,un)
endloop

//now at the end of this loop the group g2 contains units 25 distance behind the target and situated in a rectangle of 150x250 dimensions , the latter meaning how far back we seeked for units behind
//add instructions for using units in group 2 or just change the function so you can return the group g2 if necessary 
//add instructions to remove leakage

endfunction


On second thought you might not like mats as much as I do . Do the following : retain the angle (angle0) between the attacker and defender with my (see the first if condition then action ) ; set up how far behind you thing behind the attacked unit is ("tgtsize" variable) ; set yourself to how far behind units will be targeted . Use 2 groups to get units in range of the defender that are situated in a tgtsize variable ; get in group 2 units situated as far as you want from that defending unit . Now pick up all the units in group 2 and do : if they do not belong to group1 and the angle they make with the defending unit - angle0 is between some values insert them into another group or do some actions on them .
 

Dinowc

don't expect anything, prepare for everything
you mean like when backstabing a unit?
if you don't want to mess with roXplosive's giant code, here:

JASS:
globals
    private constant real MaxRange = 500.00 // this should be higher than your unit's attack range
    private constant real MinRange = 100.00 // this should be lower than your unit's attack range, the lower it is, the greater angle between
endglobals

private function Distance takes real x1, real y1, real x2, real y2 returns real
    local real dx = x2 - x1
    local real dy = y2 - y1
    return SquareRoot(dx * dx + dy * dy)
endfunction
    
    
function CheckIfBehind takes unit caster, unit target returns boolean
    local real x1 = GetUnitX(target)
    local real y1 = GetUnitY(target)
    local real x2 = GetUnitX(caster)
    local real y2 = GetUnitY(caster)
    
    local real angle = GetUnitFacing(target)
    
    local real polarX = x1 + MaxRange * Cos(angle * 0.174)
    local real polarY = y1 + MaxRange * Sin(angle * 0.174)
    
    if Distance(x2, y2, polarX, polarY) > MaxRange + MinRange then
        return true
    endif

    return false
endfunction
 

roXplosive

New Member
What if the target isn't facing the attacker ? Or did I misunderstand the question . I was thinking of selecting the units situated in a rectangle on the other side of the attacked unit with regards to the attacker .
 

roXplosive

New Member
If what I did before wasn't what you intended I have another solution here :

JASS:

function behind unit tested , unit source returns boolean
local distance = 25 //how many length units behind we consider to be behind a unit
local real facing
local real x0
local real y0
local real m

//getting unit's facing and points on a line that is perpendicular to the facing but behind the selected unit
set facing=GetUnitFacing(source)
set x0=GetUnitX(source)+distance*Cos(facing+bj_PI)
set y0=GetUnitY(source)+distance*Sin(facing+bj_PI)
set m=-1/Tan(facing) // elevation of the perpendicular to "facing"

return RsignBJ((GetUnitY(source)-y0)-m*(GetUnitX(source)-x0))*((GetUnitY(tested)-y0)-m*(GetUnitX(tested)-x0))<=0
endfunction



 
That rectangle thing is what I need but it seems to be even more complicated then the maths of LineSegments, is there shorter alternative?
 

roXplosive

New Member
I reconsidered my strategy and you can choose all units around the target of attack , get the distance to the attacker , rotate them clockwisw and check if they are inside the rectangle . This condition is one checking if P(x,y) is between certain coordinates (this will put up a bit of load on the computer but I don't think it's anything relevant):

JASS:

function Actions takes nothing returns nothing
//if event fires on damage use GetEventDamageSource()
local real attX=GetUnitX(GetAttacker())
local real attY=GetUnitY(GetAttacker())
local real defX=GetUnitX(GetTriggerUnit())
local real defY=GetUnitY(GetTriggerUnit())
local real X=250 //units 250 ??? behind the target
local real Y=75  // units 75 distance to the left/right of the target
local real tgtsize=25 //consider target size around 50 for simplicity so here we get units behind it
//now our desired rectangle will be rotated and so we need 4 points for (it)
local real xmin
local real ymin
local real xmax
local real ymax
local real dist_far

local real dist=SquareRoot((attX-defX)*(attX-defX)-(attY-defY)*(attY-defY))+tgtsize

local real angle
local group g1
local group g2
local unit un
local real unX
local real unY
local real unAngle
local real unDist

set xmin=attX+dist
set ymin=attY-Y
set xmax=attX+dist+X
set ymax=attY+Y
set dist_far=SquareRoot((attX-xmax)*(attX-xmax)+(attY-ymax)*(attY-ymax))

if attX-defX<0 then //if attacker is to the left of defender then we are in quadrant 1,4
  set angle=Atan((defY-attY)/(defX-attX))
else
 set angle= bj_PI+Atan((defY-attY)/(defX-attX))
endif


call GroupEnumUnitsInRange(g1,defX,defY,dist_far,Filter(function True)) //make a function that returns true because null here leaks
loop
  set un=FirstOfGroup(g1)
  exitwhen un==null
  set unX=GetUnitX(un)
  set unY=GetUnitY(un)
  set unDist = SquareRoot((unX-attX)*(unX-attX)+(unY-attY)*(unY-attY))
  if attX-unX<0 then
      set unAngle = Atan((unY-attY)/(unX-attX))
  else
     set unAngle = bj_PI + Atan((unY-attY)/(unX-attX))
 endif
  //rotating clockwise 
  set unX=attX+unDist*Cos(unAngle-angle)
  set unY=attY+unDist*Sin(unAngle-angle)
  if xmin<=unX and unX<=xmax and ymin<=unY and unY<=ymax then
    call GroupAddUnit(g2,un)
  endif
  call GroupRemoveUnit(g1,un)
 endloop
//now at the end of this loop the group g2 contains units 25 distance behind the target and situated in a rectangle of 150x250 dimensions , the latter meaning how far back we seeked for units behind
//add instructions for using units in group 2 or just change the function so you can return the group g2 if necessary 
//add instructions to remove leakage

endfunction
 

chobibo

Level 1 Crypt Lord
Could you clarify what you want, I don't understand what you said in your first post.

Do you want to detect collisions from behind the unit? Is it an instant detection or maintained?
 

Jesus4Lyf

Good Idea™
I have an old algorithm using vector math to detect units in a rectangle starting from a certain point, given an angle. Is that what you need?
______________
|
|
+ Point
|
|_____________

That's for 0 degrees. See, your question actually makes no sense. It could be:

..../
../
/
+ Point
\
..\
....\

Or:

|
|
|
+ Point
|
|
|

Clarify. :)
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Varine Varine:
    What a fucking disaster. Are all of the Texas people okay? I see TH is, are we the only two?
  • Varine Varine:
    How have the other states held up? I just got power back so I have no idea what's going on, we didn't get warning
  • Varine Varine:
    Why the fuck didn't they fix this ten years ago when it happened?
  • Blackveiled Blackveiled:
    I'm in it with you and TH as well. My power has been in and out, and I have a ruptured pipe that I need to fix, shouldn't be too bad to fix myself.
  • Varine Varine:
    I hope you're staying warm! Apparently the supply is coming up so hopefully we can get back to normal power soon, mine has been on for six hours now.
  • M Mulciberxp:
    My power has been off most of the last 2 days. We had a generator installed 3 years ago though, so we're staying warm. Water is another issue...
  • The Helper The Helper:
    Where I live has a pool so we are using that to get water to flush the toilets. We have enough bottled water to drink and brush teeth and stuff but it has been a few days and no shower though....
  • Varine Varine:
    I had some water in gallon jugs, and got our water back on yesterday. We don't seem to have any leaks, but I haven't crawled down there to look yet.
  • The Helper The Helper:
    still no water I cannot remember when I last showered now I know how they felt in the old west lol
  • Varine Varine:
    My poor plants are happy, they aren
  • Varine Varine:
    aren't used to going this long without water or lights or normal heat. I think a couple of them froze, but they look like they'll make it
  • Varine Varine:
    Well one of them is pretty rough but I think it was sick to begin with, that one always had some problems.
  • jonas jonas:
  • jonas jonas:
    ???
  • Ghan Ghan:
    That is such a Texas thing to say lol
  • midnight8 midnight8:
    a positive could come out of this. So many people trapped at home could put a dent in the covid numbers in Texas
  • Varine Varine:
    That dude, Tom Boyd, is really upset about the backlash from his "it's your fault you're freezing" thing because he claims he resigned before saying it, so it wasn't like he said it in his official capacity or anything.
  • jonas jonas:
    Almost as if he was saying "screw you guys, I'm going home"
  • Varine Varine:
    I'm fairly new here still but that seems to be the analogous message by several of our politicians.
  • vypur85 vypur85:
    Nobody?
  • jonas jonas:
    Hi vypur85, long time no see
  • tom_mai78101 tom_mai78101:
    Hi vypur85, long time no see.
  • The Helper The Helper:
    We are all somebody
  • Varine Varine:
    I kinda like being nobody tho.
  • The Helper The Helper:
    Voting for the NUON Controller Contest is open in the NUON-Dome NUON forum

    Members online

    Affiliates

    Hive Workshop NUON Dome
    Top