HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

GroupAddUnitsInTriangle

07-03-2008, 12:43 AM#1
Vexorian
function GroupAddUnitsInTriangle takes group whichGroup, real x1, real y1, real x2, real y2, real x3, real y3 returns nothing
Just adds all the units found inside the triangle formed by (x1,y1),(x2,y2) and (x3,y3) to the "whichGroup" unit group. The units' origin must be inside such triangle.

Differences from previous incarnations would be that it is using a library now for good implementability and avoids creating and removing a rect everytime, etc. The calculation is also faster and correct, rather than a bunch of crazy trignomotry.

Collapse JASS:
library GroupAddUnitsInTriangle initializer init
//**************************************************************************************************
//*
//*  GrupAddUnitsInTriange
//*
//*     To implement this function, copy this trigger and paste it in your map.
//* Unless of course you are actually reading the library from wc3c's scripts section, then just
//* paste the contents into some custom text trigger in your map.
//*
//**************************************************************************************************

//==================================================================================================
globals
    private rect limit
endglobals

private function makeLimit takes real x1, real y1, real x2, real y2, real x3, real y3 returns nothing
 local real maxx
 local real minx
    if (x1>x2) then
        if (x2>x3) then     //x1>x2>x3
            set maxx=x1
            set minx=x3
        elseif (x3>x1) then //x3>x1>x2
            set maxx=x3
            set minx=x2
        else                //x3>x1>x2
            set maxx=x1
            set minx=x2
        endif
    elseif (x1>x3) then //x2>x1>x3
        set maxx=x2
        set minx=x3
    elseif (x3>x2) then //x3>x2>x1 
        set maxx=x3
        set minx=x1
    else                //x2>x3>x1
        set maxx=x2
        set minx=x1
    endif

    if (y1>y2) then
        if (y2>y3) then     //y1>y2>y3
            call SetRect(limit,minx,y3,maxx,y1)
        elseif (y3>y1) then //y3>y1>y2
            call SetRect(limit,minx,y2,maxx,y3)
        else                //y3>y1>y2
            call SetRect(limit,minx,y2,maxx,y1)
        endif
    elseif (y1>y3) then //y2>y1>y3
        call SetRect(limit,minx,y3,maxx,y2)
    elseif (y3>y2) then //y3>y2>y1 
        call SetRect(limit,minx,y1,maxx,y3)
    else
        //y2>y3>y1
        call SetRect(limit,minx,y1,maxx,y2)
    endif
endfunction

globals
    private group    enumgroup
    private boolexpr checkFunc
    private group    output   
    private constant real PI2=6.28318

    private real X1
    private real X2
    private real X3
    private real Y1
    private real Y2
    private real Y3
    private real EPS=0.000000001
endglobals


private function enum takes nothing returns boolean
 local unit u=GetFilterUnit()
 local real x=GetUnitX(u)
 local real y=GetUnitY(u)
 local real r1=x*Y2-X2*y + X2*Y3-X3*Y2 + X3*y-x*Y3
 local real r2=X1*y-x*Y1 + x*Y3-X3*y + X3*Y1-X1*Y3
 local real r3=X1*Y2-X2*Y1 + X2*y-x*Y2 + x*Y1-X1*y
    if((r1<=-EPS) and (r2<=-EPS) and (r3<=-EPS)) or ((r1>=EPS) and (r2>=EPS) and (r3>=EPS)) then
        call GroupAddUnit( output, u)
    endif
 set u=null
 return false
endfunction


function GroupAddUnitsInTriangle takes group whichGroup, real x1, real y1, real x2, real y2, real x3, real y3 returns nothing
    set output=whichGroup
    set X3=x3
    set Y3=y3
    set X1=x1
    set Y1=y1
    set X2=x2
    set Y2=y2

    call makeLimit(x1,y1,x2,y2,x3,y3)
    call GroupEnumUnitsInRect(enumgroup, limit, checkFunc)
endfunction

// NOT inline friendly, (not yet), I guess that's what you get for using locations...
function GroupAddUnitsInTriangleLoc takes group whichGroup, location loc1, location loc2, location loc3 returns nothing
    call GroupAddUnitsInTriangle(whichGroup, GetLocationX(loc1),GetLocationY(loc1), GetLocationX(loc2),GetLocationY(loc2), GetLocationX(loc3),GetLocationY(loc3) )
endfunction

private function init takes nothing returns nothing
    set limit=Rect(0,0,0,0)
    set checkFunc=Condition(function enum)
    set enumgroup=CreateGroup()
endfunction

endlibrary
07-03-2008, 10:21 AM#2
waaaks
nice, i need one of these
07-07-2008, 06:59 AM#3
PandaMine
barycentric co-ordinates, nice and efficient :P