• 🏆 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!

[vJASS] Aabb

JASS:
library AABB /* v1.1 by Almia
*************************************************************************************
*
*   2D bounding boxes
*
*************************************************************************************
*
*   API
*
*   struct AABB
*
*       static method create takes real cx, real cy, real hw, real hh returns thistype
*       
*       method containsPoint takes real x, real y returns boolean
*
*       method touchesPoint takes real x, real y returns boolean
*       - same as containsPoint, but it takes account if the point is on the sides as well.
*
*       method intersectsBox takes AABB box returns boolean
*
*       method touchesBox takes AABB box returns boolean
*
*       static method operator [] takes rect r returns thistype
*       - converts a rect into a AABB
*
*       method operator rect takes nothing returns rect
*       - converts AABB into a rect 
*
*       method copy takes nothing returns thistype
*       - copy AABB
*
*       method move takes real dx, real dy returns nothing
*
*       method scaleNW takes real factor returns nothing
*       method scaleNE takes real factor returns nothing
*       method scaleSW takes real factor returns nothing
*       method scaleSE takes real factor returns nothing
*       method scaleCenter takes real factor returns nothing
*       - scale from their respective corners
*
*       method rotateNW takes real radian returns nothing
*       method rotateNE takes real radian returns nothing
*       method rotateSW takes real radian returns nothing
*       method rotateSE takes real radian returns nothing
*       method rotateCenter takes real radian returns nothing
*       - rotate from their respective corners
*
*       static method merge takes AABB a, AABB b returns thistype
*       - merges 2 AABBs by getting their Boundaries
*
*       method addNW takes real x, real y returns nothing
*       method addNE takes real x, real y returns nothing
*       method addSW takes real x, real y returns nothing
*       method addSE takes real x, real y returns nothing
*       - adjust x and y values of corners
*
*************************************************************************************/
    struct AABB
        readonly real minX
        readonly real minY
        
        readonly real maxX
        readonly real maxY
        
        readonly real centerX
        readonly real centerY
        
        readonly real halfWidth
        readonly real halfHeight
        
        readonly real width
        readonly real height
        
        static method create takes real cx, real cy, real hw, real hh returns thistype
            local thistype this = allocate()
            set centerX = cx
            set centerY = cy
            set halfWidth = hw
            set halfHeight = hh
            
            set minX = cx - hw
            set minY = cy - hh
            set maxX = cx + hw
            set maxY = cy + hh
            
            set width = halfWidth*2
            set height = halfHeight*2
            return this
        endmethod
        
        method containsPoint takes real x, real y returns boolean
            return minX < x and /*
                */ maxX > x and /*
                */ minY < y and /*
                */ maxY > y
        endmethod
        
        method touchesPoint takes real x, real y returns boolean
            return minX <= x and /*
                */ maxX >= x and /*
                */ minY <= y and /*
                */ maxY >= y
        endmethod
        
        private static method abs takes real value returns real
            if value < 0 then
                return -value
            endif
            return value
        endmethod
        
        method intersectsBox takes AABB box returns boolean
            return abs(centerX - box.centerX) < halfWidth + box.halfWidth and /*
                */ abs(centerY - box.centerY) < halfHeight + box.halfHeight
        endmethod
        
        method touchesBox takes AABB box returns boolean
            return abs(centerX - box.centerX) <= halfWidth + box.halfWidth and /*
                */ abs(centerY - box.centerY) <= halfHeight + box.halfHeight
        endmethod
        
        static method operator [] takes rect r returns thistype
            local thistype this = allocate()
            set minX = GetRectMinX(r)
            set minY = GetRectMinY(r)
            
            set maxX = GetRectMaxX(r)
            set maxY = GetRectMaxY(r)
            
            set centerX = (minX + maxX)/2
            set centerY = (minY + maxY)/2
            
            set width = maxX - minX
            set height = maxY - minY
            
            set halfWidth = width/2
            set halfHeight = height/2
            
            return this
        endmethod
        
        method operator rect takes nothing returns rect
            return Rect(minX, minY, maxX, maxY)
        endmethod
        
        method copy takes nothing returns thistype
            return create(centerX, centerY, halfWidth, halfHeight)
        endmethod
        
        method move takes real dx, real dy returns nothing
            set minX = minX + dx
            set minY = minY + dy
            
            set maxX = maxX + dx
            set maxY = maxY + dy
        endmethod
        
        private method upScale takes real factor returns nothing
            set width = width*factor
            set height = height*factor
            
            set halfWidth = width/2
            set halfHeight = height/2
        endmethod
        
        method scaleNW takes real factor returns nothing
            call upScale(factor)
            
            set centerX = minX + halfWidth
            set centerY = maxY - halfHeight
            
            set maxX = minX + width
            set minY = maxY - height
        endmethod
        
        method scaleNE takes real factor returns nothing
            call upScale(factor)
            
            set centerX = maxX - halfWidth
            set centerY = maxY - halfHeight
            
            set minX = maxX - width
            set minY = maxY - height
        endmethod
        
        method scaleSW takes real factor returns nothing
            call upScale(factor)
            
            set centerX = minX + halfWidth
            set centerY = minY + halfHeight
            
            set maxX = minX + width
            set maxY = minY + height
        endmethod
        
        method scaleSE takes real factor returns nothing
            call upScale(factor)
            
            set centerX = maxX - halfWidth
            set centerY = minY + halfHeight
            
            set minX = maxX - width
            set minY = maxY + height
        endmethod
        
        method scaleCenter takes real factor returns nothing
            call upScale(factor)
            
            set maxX = centerX + halfWidth
            set maxY = centerY + halfHeight
            
            set minX = centerX - halfWidth
            set minY = centerY - halfHeight
        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
        
        private static constant real a90 = 1.570796326
        private static constant real a270 = 4.712388980
        
        private static constant real a45 = 0.785398163
        private static constant real a135 = 2.356194490
        
        private static constant real a225 = -2.356194490
        private static constant real a315 = -0.785398163
        
        private method upRotate takes nothing returns nothing
            set centerX = (minX + maxX)/2
            set centerY = (minY + maxY)/2
            
            set width = maxX - minX
            set height = maxY - minY
            
            set halfWidth = width/2
            set halfHeight = height/2
        endmethod
        
        method rotateNW takes real radian returns nothing
            local real magnitude = SquareRoot(width*width + height*height)
            local real NWx = minX
            local real NWy = maxY
            local real SEx = NWx + magnitude*Cos(a315 + radian)
            local real SEy = NWy + magnitude*Sin(a315 + radian)
            local real SWx = NWx + height*Cos(a270 + radian)
            local real SWy = NWy + height*Sin(a270 + radian)
            local real NEx = NWx + width*Cos(radian)
            local real NEy = NWy + width*Sin(radian)
            
            set minX = min(min(NWx, SWx), min(NEx, SEx))
            set minY = min(min(NWy, SWy), min(NEy, SEy))
            
            set maxX = max(max(NWx, SWx), max(NEx, SEx))
            set maxY = max(max(NWy, SWy), max(NEy, SEy))
            
            call upRotate()
        endmethod
        
        method rotateNE takes real radian returns nothing
            local real magnitude = SquareRoot(width*width + height*height)
            local real NEx = maxX
            local real NEy = maxY
            local real SWx = NEx + magnitude*Cos(a225 + radian)
            local real SWy = NEy + magnitude*Sin(a225 + radian)
            local real SEx = NEx + height*Cos(a270 + radian)
            local real SEy = NEy + height*Sin(a270 + radian)
            local real NWx = NEx + width*Cos(bj_PI + radian)
            local real NWy = NEy + width*Sin(bj_PI + radian)
            
            set minX = min(min(NWx, SWx), min(NEx, SEx))
            set minY = min(min(NWy, SWy), min(NEy, SEy))
            
            set maxX = max(max(NWx, SWx), max(NEx, SEx))
            set maxY = max(max(NWy, SWy), max(NEy, SEy))
            
            call upRotate()
        endmethod
        
        method rotateSW takes real radian returns nothing
            local real magnitude = SquareRoot(width*width + height*height)
            local real SWx = minX
            local real SWy = minY
            local real NEx = SWx + magnitude*Cos(a45 + radian)
            local real NEy = SWy + magnitude*Sin(a45 + radian)
            local real NWx = SWx + height*Cos(a90 + radian)
            local real NWy = SWy + height*Sin(a90 + radian)
            local real SEx = SWx + width*Cos(radian)
            local real SEy = SWy + width*Sin(radian)
            
            set minX = min(min(NWx, SWx), min(NEx, SEx))
            set minY = min(min(NWy, SWy), min(NEy, SEy))
            
            set maxX = max(max(NWx, SWx), max(NEx, SEx))
            set maxY = max(max(NWy, SWy), max(NEy, SEy))
            
            call upRotate()
        endmethod
        
        method rotateSE takes real radian returns nothing
            local real magnitude = SquareRoot(width*width + height*height)
            local real SEx = maxX
            local real SEy = minY
            local real NWx = SEx + magnitude*Cos(a135 + radian)
            local real NWy = SEy + magnitude*Sin(a135 + radian)
            local real NEx = SEx + height*Cos(a90 + radian)
            local real NEy = SEy + height*Sin(a90 + radian)
            local real SWx = SEx + width*Cos(bj_PI + radian)
            local real SWy = SEy + width*Sin(bj_PI + radian)
            
            set minX = min(min(NWx, SWx), min(NEx, SEx))
            set minY = min(min(NWy, SWy), min(NEy, SEy))
            
            set maxX = max(max(NWx, SWx), max(NEx, SEx))
            set maxY = max(max(NWy, SWy), max(NEy, SEy))
            
            call upRotate()
        endmethod
        
        method rotateCenter takes real radian returns nothing
            local real magnitude = SquareRoot(halfWidth*halfWidth + halfHeight*halfHeight)
            local real cx = centerX
            local real cy = centerY
            
            local real NEx = cx + magnitude*Cos(a45 + radian)
            local real NEy = cy + magnitude*Sin(a45 + radian)
            local real NWx = cx + magnitude*Cos(a135 + radian)
            local real NWy = cy + magnitude*Sin(a135 + radian)
            local real SWx = cx + magnitude*Cos(a225 + radian)
            local real SWy = cy + magnitude*Sin(a225 + radian)
            local real SEx = cx + magnitude*Cos(a315 + radian)
            local real SEy = cy + magnitude*Sin(a315 + radian)
            
            set minX = min(min(NWx, SWx), min(NEx, SEx))
            set minY = min(min(NWy, SWy), min(NEy, SEy))
            
            set maxX = max(max(NWx, SWx), max(NEx, SEx))
            set maxY = max(max(NWy, SWy), max(NEy, SEy))
                        
            set width = maxX - minX
            set height = maxY - minY
            
            set halfWidth = width/2
            set halfHeight = height/2
        endmethod
        
        static method merge takes AABB a, AABB b returns thistype
            local thistype this = allocate()
            
            set maxX = max(a.maxX, b.maxX)
            set maxY = max(a.maxY, b.maxY)
            set minX = min(a.minX, b.minX)
            set minY = min(a.minY, b.minY)
            
            call upRotate()
            return this
        endmethod
        
        method addNW takes real x, real y returns nothing
            set minX = minX + x
            set maxY = maxY + y
            
            call upRotate()
        endmethod
        
        method addNE takes real x, real y returns nothing
            set maxX = maxX + x
            set maxY = maxY + y
            
            call upRotate()
        endmethod
        
        method addSW takes real x, real y returns nothing
            set minX = minX + x
            set minY = minY + y
            
            call upRotate()
        endmethod
        
        method addSE takes real x, real y returns nothing
            set maxX = maxX + x
            set minY = minY + y
            
            call upRotate()
        endmethod
    endstruct
endlibrary

Test code:
JASS:
struct Tester extends array
    private static AABB box1
    private static AABB box2
    
    private static lightning north
    private static lightning east
    private static lightning west
    private static lightning south
    
    private static lightning l1
    private static lightning l2
    private static lightning l3
    private static lightning l4
    
    private static constant real speed = bj_PI*0.03125
    
    private static real cur = 0
    
    private static real magnitude
    
    private static constant real a45 = 0.785398163
    private static constant real a135 = 2.356194490
        
    private static constant real a225 = -2.356194490
    private static constant real a315 = -0.785398163
        
    private static method periodic takes nothing returns nothing
        local real NWx
        local real NWy
        local real NEx
        local real NEy
        local real SWx
        local real SWy
        local real SEx
        local real SEy
        
        local AABB box1copy = box1.copy()
        set cur = cur + speed
        call box1copy.rotateCenter(cur)
        
        call MoveLightning(north, false, box1copy.minX, box1copy.maxY, box1copy.maxX, box1copy.maxY)
        call MoveLightning(east, false, box1copy.maxX, box1copy.maxY, box1copy.maxX, box1copy.minY)
        call MoveLightning(south, false, box1copy.maxX, box1copy.minY, box1copy.minX, box1copy.minY) 
        call MoveLightning(west, false, box1copy.minX, box1copy.minY, box1copy.minX, box1copy.maxY)
        
        set NEx = box2.centerX + magnitude*Cos(a45 + cur)
        set NEy = box2.centerY + magnitude*Sin(a45 + cur)
        set NWx = box2.centerX + magnitude*Cos(a135 + cur)
        set NWy = box2.centerY + magnitude*Sin(a135 + cur)
        set SWx = box2.centerX + magnitude*Cos(a225 + cur)
        set SWy = box2.centerY + magnitude*Sin(a225 + cur)
        set SEx = box2.centerX + magnitude*Cos(a315 + cur)
        set SEy = box2.centerY + magnitude*Sin(a315 + cur)
        
        call MoveLightning(l1, false, NEx, NEy, NWx, NWy)
        call MoveLightning(l2, false, NWx, NWy, SWx, SWy)
        call MoveLightning(l3, false, SWx, SWy, SEx, SEy)
        call MoveLightning(l4, false, SEx, SEy, NEx, NEy)
        
        call box1copy.destroy()
    endmethod
    
    private static constant timer t = CreateTimer()
    
    private static method onInit takes nothing returns nothing
        set box1 = AABB.create(0, 0, 256, 256)
        set box2 = box1.copy()
        set magnitude = SquareRoot(box2.halfWidth*box2.halfWidth + box2.halfHeight*box2.halfHeight)
        
        set north = AddLightning("CLPB", false, box1.minX, box1.maxY, box1.maxX, box1.maxY)
        set east = AddLightning("CLPB", false, box1.maxX, box1.maxY, box1.maxX, box1.minY)
        set south = AddLightning("CLPB", false, box1.maxX, box1.minY, box1.minX, box1.minY) 
        set west = AddLightning("CLPB", false, box1.minX, box1.minY, box1.minX, box1.maxY)
        
        set l1 = AddLightning("CLPB", false, box2.minX, box2.maxY, box2.maxX, box2.maxY)
        set l2 = AddLightning("CLPB", false, box2.maxX, box2.maxY, box2.maxX, box2.minY)
        set l3 = AddLightning("CLPB", false, box2.maxX, box2.minY, box2.minX, box2.minY) 
        set l4 = AddLightning("CLPB", false, box2.minX, box2.minY, box2.minX, box2.maxY)
        
        call TimerStart(t, 0.03125, true, function thistype.periodic)
        
        call PanCameraTo(0, 0)
    endmethod
endstruct

1.1
- Added merge method
- Added add methods
1.0
- Release
 

Attachments

  • AABB.w3x
    21.9 KB · Views: 63
Last edited:
Top