• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

Some new snippets

Status
Not open for further replies.

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Hey. I'm making new snippets for my platform system thingy. I post'em here instead since I'm not sure they are acceptable or not.

1. Angled Rect
Just like rect, but you can rotate it at will. One day I will expand this to a polygon system, where you can define and modify it's vertex freely. Supports any shape of polygons, both regular and irregular. I have started to work on this but decided to pause it until my platform system is completed.

JASS:
library AngledRect
    
    /*  Illustration.
              rotation < .
                         | width
            (ax, ay) ____|____ (bx, by)
                    |////|////|
                    |////•////| > height
                    |/////////|
            (cx, cy) ¯¯¯¯¯¯¯¯¯ (dx, dy)
    */
    globals
        private constant real AREA_TOLERATION = 25.0
    endglobals
    
    struct AngledRect
    
        private  real d
        private  real a
        
        readonly real ax
        readonly real ay
        readonly real bx
        readonly real by
        readonly real cx
        readonly real cy
        readonly real dx
        readonly real dy
        readonly real x
        readonly real y
        readonly real width
        readonly real height
        
        private static method getArea takes real a, real b, real c returns real
            local real s = (a+b+c)/2
            return SquareRoot(s*(s-a)*(s-b)*(s-c))
        endmethod
        
        private method repaint takes nothing returns nothing
            
            local real w = .width/2
            local real h = .height/2
            local real a
            
            set .d = SquareRoot(w*w+h*h)
            
            set a = .a + Atan(w/h)
            set .ax = .x + .d * Cos(a)
            set .ay = .y + .d * Sin(a)
            call CreateUnit(Player(0), 'oeye', .ax, .ay, a*bj_RADTODEG)
            
            set a = a + bj_PI
            set .dx = .x + .d * Cos(a)
            set .dy = .y + .d * Sin(a)
            call CreateUnit(Player(0), 'oeye', .dx, .dy, a*bj_RADTODEG)
            
            set a = .a - Atan(w/h)
            set .bx = .x + .d * Cos(a)
            set .by = .y + .d * Sin(a)
            call CreateUnit(Player(0), 'oeye', .bx, .by, a*bj_RADTODEG)
            
            set a = a + bj_PI
            set .cx = .x + .d * Cos(a)
            set .cy = .y + .d * Sin(a)
            call CreateUnit(Player(0), 'oeye', .cx, .cy, a*bj_RADTODEG)
            
        endmethod
        
        method operator angle= takes real a returns nothing
            set angle = a*bj_DEGTORAD
            call repaint()
        endmethod
        
        method operator angle takes nothing returns real
            return a*bj_RADTODEG
        endmethod
        
        method move takes real x, real y returns nothing
            set .x = x
            set .y = y
            call repaint()
        endmethod
        
        method size takes real width, real height returns nothing
            set .width  = width
            set .height = height
            call repaint()
        endmethod
        
        method containsPoint takes real x, real y returns boolean
            
            local real da = SquareRoot((x-.ax)*(x-.ax)+(y-.ay)*(y-.ay))
            local real db = SquareRoot((x-.bx)*(x-.bx)+(y-.by)*(y-.by))
            local real dc = SquareRoot((x-.cx)*(x-.cx)+(y-.cy)*(y-.cy))
            local real dd = SquareRoot((x-.dx)*(x-.dx)+(y-.dy)*(y-.dy))
            
            return getArea(.width, da, db)+getArea(.height, db, dd)+getArea(.width, dd, dc)+getArea(.height, dc, da) <= .width*.height+AREA_TOLERATION
        endmethod
        
        method containsWidget takes widget w returns boolean
            return containsPoint(GetWidgetX(w), GetWidgetY(w))
        endmethod
        
        method containsUnit takes unit u returns boolean
            return IsUnitInRangeXY(u, .x, .y, .d) and containsPoint(GetUnitX(u), GetUnitY(u))
        endmethod
        
        static method create takes real x, real y, real width, real height, real angle returns thistype

            local thistype this = allocate()
            
            set .x = x
            set .y = y
            set .a = angle*bj_DEGTORAD
            set .width  = width
            set .height = height
            call repaint()
            
            return this
        endmethod
        
    endstruct
    
endlibrary

Excuse me. I still create some units in repaint method for testing purpose, to visualize the rect area.

Demo
JASS:
scope demo1 initializer init
    
    globals
        private AngledRect R
    endglobals
    
    private function tick takes nothing returns nothing
        if R.containsWidget(some_unit) then
            call DisplayTimedTextToPlayer(Player(0),0,0,1,"contain")
        endif
    endfunction
    
    private function init takes nothing returns nothing
    
        set R = AngledRect.create(-2000, -2000, 500, 100, 245)
        call TimerStart(CreateTimer(), 0.5, true, function tick)
        
    endfunction
    
endscope

2. GetDestructableZ
This only works for a walkable destructable. Along with many other restrictions (e.g. pathing map). And this function is heavy.
JASS:
library GetDestructableZ initializer init uses UnitZ
    
    globals
        private unit dummy
    endglobals
    
    function GetDestructableZ takes destructable d returns real
        
        local real x = GetDestructableX(d)
        local real y = GetDestructableY(d)
        local real z1
        local real z2
        local destructable d2
        
        call SetUnitX(dummy, x)
        call SetUnitY(dummy, y)
        set z1 = GetUnitZ(dummy)
        set d2 = CreateDestructableZ(GetDestructableTypeId(d), x, y, z1, 0, 1, 0)
        set z2 = GetUnitZ(dummy)
        call RemoveDestructable(d2)
        set d2 = null
        
        return z1-(z2-z1)
    endfunction
    
    private function init takes nothing returns nothing
        
        set dummy = CreateUnit(Player(PLAYER_NEUTRAL_PASSIVE), 'hpea', 0, 0, 0)
        call PauseUnit(dummy, true)
        call ShowUnit(dummy, false)
        
    endfunction
    
endlibrary

Demo
JASS:
        call BJDebugMsg(R2S(GetDestructableZ(CreateDestructableZ('B000', -2000, -2000, 123.456, 180, 1, 1))))
It will print exactly 123.456

Feedback pls.
 
Last edited:
Level 24
Joined
Aug 1, 2013
Messages
4,657
ContainsPoint could be much better.

In my Polygon struct, I use a ray casting algorithm.
In Shadow Flux' library about some 3d rectangle, he also uses that algorithm but solely for the purpose of rectangles.
You could check it out.

I also dont really understand the point of IsUnitInRangeXY(u, .x, .y, .d).
Unless it is super efficient, you should rather just make a minX minY, maxX maxY for bounds and check the X and Y withing those bounds.

I suppose you could make the data only ax, ay, bx, by, etc without the width and height.
Then have methods that recalculate the x and y of each point and have width and height and angle as parameters.

method move takes real x, real y returns nothing
Just pick all the X and Y variables and add the x and y to it.
No Cos, Sin or whatever.
(Repaint shouldnt be necessary in any method actually and just be used for testing purpose.)

You can check out the rotate method in my Polygon struct as well... Just for the sake of efficiency.

Equal as scaling.
You should have a function that scales the rectangle by xFactor and yFactor.
Look at my Polygon struct how I have implemented it.
Then you can have a redirect method of setSize takes real w, real h that calls scale by call scale(w/this.width, h/this.height).
Be aware that you shouldnt call this method on a rect with 0 width or height... dunno why you want that in the first place at all.

Just my opinion... and maybe just for the sake of being able to use it in max efficiency, you shouldnt be using *bj_DEGTORAD
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
Well, I'm not really intrigued to optimize those snippets. I was just creating them for my platform system temporarily since I can't find existing one anywhere. At least they were not appearing in google. If you have created one already (like Flux's system) and you are sure it's better, I will certainly use it instead. But for your information, in my AngledRect I use an algorithm that's admitted to be working for any shape of polygon, and they said it's fairly efficient. But perhaps, it's not in wc3. Since function call costs a little.

@wietlol: I can't find your polygon thingy.
 
Status
Not open for further replies.
Top