HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Bit of angular knockback stuffs.

08-05-2008, 10:27 AM#1
EquippedChaos
Darkwulfv again.
Okay, so I have this setup:

C = Caster
T = Target
Green Dots = Units in the way
Thick black line = Path
Thin black lines = Perpendicular lines I want units to travel



Because my school is crap and didn't teach me anything about nothing, I need to know (and hopefully get some example code) for the following:
  • How to detect a unit is on the caster's left, right, or center (if somehow they were at that precise point)
  • Get an angle perpendicular to the cast angle
    (Would this be as easy as adding 90 degrees (whatever it is in radians) to the angle?)

The rest I can do (the minor knockback, point projecting, etc.) on my own.
For the record, goldendercon doesn't know either.

Thanks!
08-05-2008, 10:44 AM#2
Vestras
Well, when detecting left and right I would probably store the unit's facing in a variable. Now, then I would put an if then else and in the if I would check if the caster's facing is in the curve of 90 - 270 and the other way around with the other way. Now, put an if then else again and check if the GetEnumUnit() is in the angle of 90 - 270, if it is, then find the middle between 90 and 270 and knock it towards that angle.
08-05-2008, 11:04 AM#3
darkwulfv
The caster's facing angle has nothing to do with the target's facing angle.

If caster were facing North, and the unit was facing Southwest, he wouldn't get knocked back, even if he were in the direct path. Plus, it wouldn't perpendicular.

What little logical math skillz I have tells me that adding/subtracting 90 degrees (whatever that is in radians) to the main angle will give me a perpendicular angle with which to direct a knockback; all I need to know now is whether the units are on the left or right of the caster.

EDIT: D'oh. I forgot to post from the team account; ah well.
08-05-2008, 11:14 AM#4
Vestras
I just said what I would do. When I'm knocking back, I make the unit that are knocked face the angle, and then make the unit slide towards its facing.
08-05-2008, 11:18 AM#5
EquippedChaos
Ooh, that's what you meant; That's not what I need to know though. I just need to find if a unit is on the left or right of the caster's angle.
08-05-2008, 11:28 AM#6
Fireeye
So you want a function which has 3 different return values, right?
- unit on the left side
- unit on the right side
- unit exactly on the path
08-05-2008, 11:31 AM#7
EquippedChaos
A function works, or just the code to do so. Actually a function would be great. It could return an integer;

1 = left
2 = right
3 = center

Angles need to be radians, obviously.
08-05-2008, 12:11 PM#8
DioD
basic settings
Code:
set range = DistanceBetweenPoints(Caster,Target)
set angle = AngleBetweenPoints(Caster,Target)
set middle = PolarProjectionBJ(Caster,range/2,angle)
set group = GroupEnumUnitsInRangeOfLoc(group,middle,range+range/2,null)

per unit enumed calls

Code:
if AngleBetweenPoints(Caster,Target) > AngleBetweenPoints(Caster,Enumed) then

//unit below line

set reflect angle = AngleBetweenPoints(Caster,Target) - 90

else 

set reflect angle = AngleBetweenPoints(Caster,Target) + 90

have no syntax tool by hand, but this shoud work
Attached Images
File type: jpgIgnitionDrawing2.jpg (17.9 KB)
File type: jpgIgnitionDrawing2.jpg (17.9 KB)
File type: jpgIgnitionDrawing2.jpg (17.9 KB)
08-05-2008, 01:17 PM#9
darkwulfv
Well besides BJ abuse, this looks like it would work just fine. Thanks a ton, I'll put it to work.
(Too lazy to get on the team account =p )
08-06-2008, 08:18 AM#10
Strilanc
Using trigonometry for this problem is unnecessary, and expensive. This is the type of case where vector math shines.

Collapse JASS:
//u = vector from caster to target point
set ux = targetX-casterX
set uy = targetY-casterY
//p = u rotated 90 degrees counter clockwise
set px = -uy
set py = ux
//v = vector from caster to unit
set vx = unitX-casterX
set vy = unitY-casterY
//s = scalar projection of v onto p
set s = (vx*px+vy*py) / SquareRoot(vx*vx + vy*vy)
//s is our magic number, it is the distance from the center line
//if s > 0, the unit is to the left [counter clockwise]
//if s < 0, the unit is to the right [clockwise]
//if |s| is small, then the unit is close to the line
//if |s| is large, then the unit is far from the line. probably missed.
//if s == 0, the unit is on the line

//notice that you can optimize the code
//for example, if all you want is the sign of s, you don't need the division + square root when computing s

Try the math out on some easy cases, it really is impressive that it works. This also combines your 'is the unit even hit by the projectile?' step, because you can check if |s| <= width of projectile/2.
08-06-2008, 02:18 PM#11
darkwulfv
I think I heard somewhere, from someone like Griff or Dusk, that Cos and Sin were not expensive functions. And I'm honestly a lot more comfortable working with trigonometry, since it's right were I am mathematics-wise in school.

Thanks for your effort though. And uhh, I think I might've forgotten to mention that the arrow is the caster. Charging. And I only groupenum units within like 35 range of him, which would be immediate collision and thus cause problems. So I'm not grabbing all units in X big radius, I'm just grabbing units who happen to be next to the caster while he runs to the target.
08-06-2008, 04:40 PM#12
Rising_Dusk
Cos and Sin aren't expensive, but it's still cheaper to not use them if you can avoid them (Obviously). Vector math is wonderful because it's just happy addition (Usually), which is far cheaper than the trigonometry functions. (Although square root sucks big time, so Stril's example is great if you only need the sign of s)

To be fair, though, you can just use an (Atan2(dy, dx) * 180 / bj_PI) call to get exactly the angle in degrees you want to knock the other guy back to. Trig was invented for a reason -- Makes it easy.
08-06-2008, 04:48 PM#13
EquippedChaos
<-- Doesn't even know trigonometry well, let alone vector math.

Me again (darkwulfv). I'm having trouble, and Cos/Sin math seems to be the issue. It's in another thread ("Charging... What a pain."), and if vector math is the solution to an easier life with this, then I'll learn it.
08-06-2008, 04:53 PM#14
Rising_Dusk
Everyone in their right mind should know Vector Math anyways, but it isn't necessary to apply it to WC3 unless you're good at translating the math involved to code.

By the way, if you look at my knockback system, I just updated it to allow knocking back adjacent units. It seems it already does what you wanted to code. I use the impact angle for the secondary knockbacks, not the perpendicular. If you want the perpendicular, please, read over Stril's post until it makes sense.
08-06-2008, 05:16 PM#15
EquippedChaos
Then my school is definitely not in their right minds, or I'd probably know it already.

Well I can't even know if what I've got already works; the charging doesn't work properly (and thus the caster never comes in contact with units)...