HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Pick Units Between two points.

10-27-2007, 08:08 PM#1
SkriK
The spell that's related is Blink.

I want to "Unit Group - Pick Units" on the units between
Zoom (requires log in)

It possible with gui?
Attached Images
File type: gif2.gif (3.3 KB)
10-27-2007, 08:19 PM#2
Captain Griffen
Yes.

Advisable?

No.
10-27-2007, 08:51 PM#3
Silvenon
It's not hard, you just need to create a region from point A to point B with a certain width and the units in that region will be the ones you want (probably)
10-27-2007, 09:19 PM#4
SkriK
Well, i seem to have found out the pick part, but now it only picks within a thin line, if anyone knows how to set width, please tell.
EDIT: Nope, was faulty.
10-27-2007, 09:31 PM#5
TEC_Ghost
I'd say use Offsets to set the width with the way you're doing it there.

Or another way to do it is to create dummy units along the line and select units within a certain range of them then get rid of em, that'd take a bit more work, but it seems more controllable.
10-27-2007, 09:43 PM#6
CommanderZ
Let's say the width of the line is W. Then you can pick all units in in range of W/2 every...lets say W/4 points and add them to the group. It is not 100% exact, but it should serve it purpose well for shorther distances (otherwise you would have to make too much of these circles and it'd be CPU demanding)
10-27-2007, 10:31 PM#7
Strilanc
Step 0: A = location of caster, B = location of target, W = width of area
Step 1: compute the line C passing through the points A and B
Step 2: compute the lines D and E perpendicular to the line C and passing through the points A and B respectively
Step 3: compute the two unique points F and G on the line D a distance W/2 from the point A
Step 4: compute the lines H and I parallel to the line C and passing through the points F and G respectively
Step 5: Your area is bounded by the lines D, E, H and I
10-27-2007, 10:49 PM#8
SkriK
How do i "compute lines?"
And i might be very wrong, but this is how i interpreted those steps.
Zoom (requires log in)
Attached Images
File type: gif3.gif (5.2 KB)
10-27-2007, 10:58 PM#9
PipeDream
This question comes up a lot.

1. Enum units in a circle that has (A+B)/2 as a center and |A-B|/2 as radius. You could also use a rectangle with A B as corners, depends how you want to handle the end points
2. Filter down to units with distance from line[1][2] A-B less than your criterion.
10-27-2007, 11:09 PM#10
SkriK
That's like, ?????????????
10-27-2007, 11:13 PM#11
cohadar
Quote:
Originally Posted by PipeDream
This question comes up a lot.

1. Enum units in a circle that has (A+B)/2 as a center and |A-B|/2 as radius. You could also use a rectangle with A B as corners, depends how you want to handle the end points
2. Filter down to units with distance from line[1][2] A-B less than your criterion.

Or he could simply use 2 inTriangle functions...
10-28-2007, 02:58 AM#12
Malf
This may be what you're looking for.

You can find other geometrical functions here
10-28-2007, 03:21 AM#13
MaD[Lion]
hm i think a good way is to pick every unit in a circle with radius as point A->B divided by 2. and then for all this units, check if they are inside polygon :D damn i love this system even tho i never used it
10-28-2007, 09:07 AM#14
cohadar
OK THIS IS WRONG:
Collapse JASS:
function GroupEnumUnitsInLine takes group g, real x1, real y1, real x2, real y2, real width returns nothing
    local real angle = Atan2(y2-y1,x2-x1)
    local real dist = SquareRoot( (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1) )
    local real cdist = 0
    local group temp
    loop
        exitwhen (cdist > dist)
        set temp = CreateGroup()
        call GroupEnumUnitsInRange(temp,x1,y1,width/2,null)
        set bj_wantDestroyGroup = true
        call GroupAddGroup(temp,g)
        set x1 = x1+((width/4)*Cos(angle))
        set y1 = y1+((width/4)*Sin(angle))
        set cdist = cdist + (width/4)
    endloop
    set temp = null
endfunction

First of all it is more CPU intensive than it needs to be, second it does not work in all cases.
I will make one without loop, geez some people really don't know math.

Brb.

EDIT:
I am at work now so I don't have time/tools to do this,
but not to leave you without any clue about what I meant:
Hidden information:
Zoom (requires log in)


See the current algorithm is using multiple EnumInCircle functions,
since circles are overlapping it is doing a lot of unnecessary work,
and it even misses some units (red fields)

How it should be done is to enum all units in enclosing circle
call GroupEnumUnitsInRange(temp,(x1+x2)/2,(y1+y2)/2,dist/2,null)
and then do a ForGroup to remove all units that are not in between 2 lines parallel to units moving line.

Two shorter lines do not need to be checked because width is shorter than length and parts of enclosing circle are almost strait lines there.

I leave implementation of this as a homework for you peoples.
Attached Images
File type: pngline.PNG (16.0 KB)
10-28-2007, 02:56 PM#15
Guesst
When you are going through each unit in the circle, I think it would be these calculations. It is just projecting the startpoint->endpoint and startpoint->unit vectors and then getting the other side of the triangle. Unless there some polygon system, in which case that would probably be easier.

linex = endpointx - startpointx
liney = endpointy - startpointy
unitx = unitx - startpointx
unity = unity - startpointy
linelengthsqared = linex*lineX + liney*liney
dotproduct = linex*unitx + liney*unity
projectionx = linex*dotproduct/linelengthsquared
projectiony = liney*dotproduct/linelengthsquared
projectionlengthsquared = projectionx*projectionx+projectiony*projectiony
unitlengthsquared = unitx*unitx + unity*unity
distancesquared = unitlengthsquared - projectionlengthsquared
it is in the area if distancesquared <= the square of the width of the area you want