HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Some simple math stuff

11-12-2007, 03:54 PM#1
darkwulfv
Ok, my school has yet to teach me how to determine things like angle from points... and stuff. (Like trig, etc.)

So... How do you get the angle between 2 points? (Besides using the BJ "AngleBetweenPoints", which breaks down into some long string of GetLocationX, etc.) Or would it be better to use X and Y reals? (And how would you do that?)

I'm sorry to ask such a stupid question, but I haven't a clue how. Doesn't it involve Sine and Cosine?
Oh, and should I be using Radians or Degrees? (And how do you use each, in JASS). Again, sorry for asking a stupid question. Once it's answered I'll tack into a function so I won't forget how to do it.
11-12-2007, 04:04 PM#2
cohadar
No it does not. (involve sine or cosine)

Simply use Atan2 directly, it will return angle between 2 points in radians


Atan2(Yb-Ya, Xb-Xa) will return angle between points A and B
pointing in the direction from A to B

Zoom (requires log in)

remember y goes before x in atan...
Attached Images
File type: pngatan2.PNG (3.9 KB)
11-12-2007, 04:08 PM#3
darkwulfv
Ah, thanks. I kinda figured it half-out on my own by looking at it hard enough. But I didn't know if I was doing it right.

While I'm here... Using the angle, how would you find a point, say, 500 units away from point A, but along the angle?

Here's what I'm trying to do... Because honestly, im completely stumped. You target a unit, it gets stunned. Then, continuing on for 500 distance, all units along the same angle (within say 50 distance of the 'line') are also stunned. However, I've never worked with math like this before, so I'm clueless.

I thought of picking every unit within 500 of the target, and checking if their angle relative to the caster was within X radians of the major angle, and stunning them if it was. (Then again, are radians used any different than normal reals?)
11-12-2007, 04:54 PM#4
cohadar
points along line are calculated like this:

X = distance * Cos(angle)
Y = distance * Sin(angle)

Angle is in radians ofc.

Your problem is called "get all units in a line"

Now the catch there is that noone made any decent function for that.
I have seen some half-ass solutions but none of them were any good.

Guess it is time I finally make one of my own.
(be back in an hour or so.)
11-12-2007, 04:57 PM#5
darkwulfv
I knew Cos and Sine would be used somewhere in here.

Now, I've got this:
(Quick explanation: Takes the angle of the picked unit from the group of enemies in 500 radius of the target and compares it to the original angle. If it's greater or less than the angle + or - an amount (the width of the 'line), then the unit is not in that line)
Collapse JASS:
 
//MasterAngle is the original angle from the caster to the target.
  loop
  set f = FirstOfGroup(UnitsAlongLine)
  set MinorAngle = Atan2(GetUnitY(f) - Castery, GetUnitX(f) - Casterx)
    exitwhen f == null
    if MinorAngle < MasterAngle - Line_Radius and MinorAngle > MasterAngle + Line_Radius then
      call GroupRemoveUnit(UnitsAlongLine, f)
    else
      set Targets[i] = f
      set i = i + 1
      call GroupRemoveUnit(UnitsAlongLine, f)
    endif
  endloop
I'm aware it's a hideous blob, but it's the only thing I could really think of doing. Would that work?
11-12-2007, 05:14 PM#6
cohadar
No it wouldn't.

Zoom (requires log in)

EDIT:

I found this: http://www.thehelper.net/forums/showthread.php?t=46127
Attached Images
File type: pngcone.PNG (2.8 KB)
11-12-2007, 06:46 PM#7
darkwulfv
Ah, dammit. I thought that'd work.

Well, I'll look at the line template. I really just need to sort through it and see how he got the line. The spell I'm making is different from a Carrion Swarm type spell.
(Ah, screw that. It's horrendously confusing, spacing is terrible. I can hardly read a thing... Also, i haven't a clue what to look for anyways)

Basically... What I need is to make 2 lines parallel to the master angle. These lines are the 'parameter' of the spell. If I knew a way to determine where to place the 2 dummy units (side to side with the target) I'd be able to do this without much of a problem)

Let's make a small diagram.
Code:
o
      z________o________
       o       o
X    T---------o----o--- (Master angle)
      z ___o__o__________
                 o         o
Now, X is the caster. T is the first target. The solid lines are the 'parameters'. Let's say they're 20 Wc3 units apart. Any 'o' inside the 2 parameter lines are affected, any outside are not. A 'z' represents a dummy unit (placed next to the target 10 units apart from the master angle) used as the start of the parameter. Now, if it were like this (horizontal) that'd be easy. But let's say the master angle is a 36.224 degree (whatever that is in radians) angle. How would I determine where to place the 'z's?

EDIT: I'm just gonna make a thread for this. It's getting annoying.
11-12-2007, 07:29 PM#8
Here-b-Trollz
Collapse JASS:
/*
c=Caster
t=Target
a=Dummy One
b=Dummy Two
D='Radius (half the width) of your line'
N=90*bj_DEGTORAD
*/

local real cx=GetUnitX(c)
local real cy=GetUnitY(c)
local real tx=GetUnitX(t)
local real ty=GetUnitY(t)
local real ang=Atan2(ty-cy,tx-cx) //Only part I'm not sure about (The angle might be messed up)
local real face=ang*bj_RADTODEG
local unit a=CreateUnit(blah,blah,tx+Cos(ang+N)*D,ty+Sin(ang+N)*D,face) //This will create 'a' offset D distance from 't' at the master angle PLUS (+) 90
local unit b=CreateUnit(blah,blah,tx+Cos(ang-N)*D,ty+Sin(ang-N)*D,face) //This will do the same thing, but offset at the master angle MINUS (-) 90
11-12-2007, 07:34 PM#9
darkwulfv
So... That, basically, will make 2 units parallel to the master angle? Looks simple enough. Thanks and +repped. (Gonna go test it now.)

Except... I needed it in Radians. Oh well. I'll change it. (Removing the bj_RADTODEG's will deliver the same effect, but in usage of radians, right?)

EDIT: Yup, everything works without the bj_RADTODEG's. The only difference is the units weren't facing the master angle's direction... which doesn't matter anyways. Thanks a lot for that code!
11-12-2007, 07:39 PM#10
Salbrismind
Your first attempt is okay if you don't mind its consequence (cohadar's diagram). But to make dummy units beside the hero like that is pretty simple, unfortunately using the two lines as parameters is super confusing... If the width of the line is only 10 why not just make 4 dummy units (2 on both side of the target) and then use your unit detection without any width so it doesn't fan out. Better yet round the angles to one decimal then compared then that way you are more likely to get matches if they are close by.
11-12-2007, 07:44 PM#11
cohadar
Here-b-Trollz, the rep stealer.
11-12-2007, 07:54 PM#12
darkwulfv
Salbris, Here-b-trollz already solved the issue just fine. All I need to do is create the dummy units, then, from their positions, use a formula that places another 2 points X distance away (at that angle).

But... Hmm... How would I check that units are inside that box created? (I don't know how to do it according to your descriptions.)
11-12-2007, 08:10 PM#13
Ammorth
You can either check if the units are so far away from the line of the caster, or check if the unit is within the square you made.

For square check: http://www.wc3campaigns.net/showthread.php?t=96543
for distance, read: http://www.geometrictools.com/Docume...ePointLine.pdf
11-12-2007, 08:22 PM#14
darkwulfv
Well, seeing as how option 2 looks like a bunch of gibberish to me, I think I'll be going with option 1. Thanks.

Well, actually. Option 2 was a bunch of random gibberish, but I have no idea how to use or implement Option 1. The system describes how to use it, but not how to implement it (or what to copy over). Also, this is a spell request and I'd rather not use an outside system, which would make implementing the spell even harder.

I haven't been able to think of a single method on how to work this. If there's a way to counter the fanning-out consequence of my first idea, then I'll be all set, but I don't know how to do that. (Which is why I needed the 2 dummy units on the side of the target, so they can be the parameter bases. But then that brought up the issue of detecting units within that area... Which is where I am now.)

Oh wait! I think I've got one. It may seem very inefficient in terms of speed, but here we go anyways.

Place a dummy unit (or make a point. You get the idea) every, say 50 units along the angle line. Then just check, for each dummy, if there are units in their midst of 50 radius. (I would check for overlapping units so they aren't hit multiple times). That way, I should get all the units along the line within X radius... right?
11-12-2007, 11:55 PM#15
Salbrismind
Quote:
Originally Posted by darkwulfv
Well, seeing as how option 2 looks like a bunch of gibberish to me, I think I'll be going with option 1. Thanks.

Well, actually. Option 2 was a bunch of random gibberish, but I have no idea how to use or implement Option 1. The system describes how to use it, but not how to implement it (or what to copy over). Also, this is a spell request and I'd rather not use an outside system, which would make implementing the spell even harder.

I haven't been able to think of a single method on how to work this. If there's a way to counter the fanning-out consequence of my first idea, then I'll be all set, but I don't know how to do that. (Which is why I needed the 2 dummy units on the side of the target, so they can be the parameter bases. But then that brought up the issue of detecting units within that area... Which is where I am now.)

Oh wait! I think I've got one. It may seem very inefficient in terms of speed, but here we go anyways.

Place a dummy unit (or make a point. You get the idea) every, say 50 units along the angle line. Then just check, for each dummy, if there are units in their midst of 50 radius. (I would check for overlapping units so they aren't hit multiple times). That way, I should get all the units along the line within X radius... right?

Yes, but you need to figure out which might be a better choice, it is possible to do both but the calculation might be a lot faster and a lot less buggy.