- Joined
- Apr 24, 2012
- Messages
- 5,111
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
Last edited: