| 07-03-2008, 12:43 AM | #1 |
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. 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 |
nice, i need one of these |
| 07-07-2008, 06:59 AM | #3 |
barycentric co-ordinates, nice and efficient :P |
