• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[WIP]Polygon

Status
Not open for further replies.
JASS:
library Polygon requires Real2D Rects
    
    private module Init
        private static method onInit takes nothing returns nothing
            call init()
        endmethod
    endmodule
    
    struct Polygon extends array
        private Coord head
        private static integer array prev
        private static integer array next
        
        readonly Coord center
        readonly integer points
        
        private Rects AABB
        
        private static thistype array recycler
        
        private static method allocate takes nothing returns thistype
            local thistype this = recycler[0]
            if recycler[this] == 0 then
                set recycler[0] = this + 1
            else
                set recycler[0] = recycler[this]
            endif
            set center = Coord.create(0, 0)
            set AABB = Rects.create(0, 0, 1, 1)
            set points = 0
            set head = 0
            return this
        endmethod
        
        private method deallocate takes nothing returns nothing
            set recycler[this] = recycler[0]
            set recycler[0] = this
        endmethod
        
        private static method min takes real a, real b returns real
            if a < b then
                return a
            endif
            return b
        endmethod
        
        private static method max takes real a, real b returns real
            if a > b then
                return a
            endif
            return b
        endmethod
        
        static method create takes Coord A, Coord B, Coord C returns thistype
            local thistype this = allocate()
            set head = A
            set prev[A] = C
            set next[A] = B
            set prev[B] = head
            set next[B] = C
            set prev[C] = B
            set next[C] = A
            set center.x = (A.x + B.x + C.x)/3
            set center.y = (A.y + B.y + C.y)/3
            set AABB.minX = min(min(A.x, B.x), C.x)
            set AABB.minY = min(min(A.y, B.y), C.y)
            set AABB.maxX = max(max(A.x, B.x), C.x)
            set AABB.maxY = max(max(A.y, B.y), C.y)
            call AABB.refresh()
            set points = 3
            return this
        endmethod
        
        method destroy takes nothing returns nothing
            call deallocate()
            call center.destroy()
            set head = 0
            set points = 0
        endmethod
            
        method refresh takes nothing returns nothing
            local Coord p = next[head]
            local real sx = p.x
            local real sy = p.y
            local real minX = p.x
            local real minY = p.y
            local real maxX = p.x
            local real maxY = p.y
            set p = next
            loop
                set minX = min(p.x, minX)
                set minY = min(p.y, minY)
                set maxX = min(p.x, maxX)
                set maxY = min(p.y, maxY)
                set sx = sx + p.x
                set sy = sy + p.y
                exitwhen p == head
                set p = next
            endloop
            set center.x = sx/R2I(points)
            set center.y = sy/R2I(points)
        endmethod
        
        method has takes Coord coord returns boolean
            local Coord p = next[head]
            loop
                if coord == p then
                    return true
                endif
                exitwhen p == head
                set p = next
            endloop
            return false
        endmethod
        
        method insert takes Coord coord returns nothing
            if not has(coord) then
                set points = points + 1
                set next[coord] = head
                set prev[coord] = prev[head]
                set next[prev[head]] = coord
                set prev[head] = coord
                call refresh()
            endif
        endmethod
    
        method remove takes Coord coord returns nothing
            if has(coord) and points > 3 then
                set next[prev[coord]] = next[coord]
                set prev[next[coord]] = prev[coord]
                if head == coord then
                    set head = next[coord]
                endif
                set points = points - 1
                call refresh()
            endif
        endmethod
        
        method rotate takes real rad returns nothing
            local Coord p = next[head]
            local real tx
            loop
                set tx = p.x
                set p.x = p.x*Cos(rad) - p.y*Sin(rad)
                set p.y = p.y*Cos(rad) + tx*Sin(rad)
                exitwhen p == head
                set p = next
            endloop
            call refresh()
        endmethod
        
        method scale takes real factor returns nothing
            local Coord p = next[head]
            local real dist
            loop
                set p.x = center.x + (p.x - center.x)*factor
                set p.y = center.y + (p.y - center.y)*factor
                exitwhen p == head
                set p = next
            endloop
            call refresh()
        endmethod
        
        method containsPoint takes real x, real y returns boolean
            local Coord p = next[head]
            local boolean result = false
            loop
                if ((p.y >= y) != (head.y >= y)) and (x < ((head.x - p.x)*(y - p.y)/(head.y - p.y) + p.x)) then
                    set result = not result
                endif
                exitwhen p == head
                set p = next
            endloop
            return result
        endmethod
        
        method intersects takes Polygon p returns boolean
            return false
        endmethod
    endstruct
endlibrary
 
Status
Not open for further replies.
Top