UNPKG

meta-next

Version:

183 lines (150 loc) 3.97 kB
import { clamp } from "./Common" class AABB { constructor(x, y, width, height) { this.x = x || 0 this.y = y || 0 this.width = width || 0 this.height = height || 0 this.minX = this.x this.minY = this.y this.maxX = this.x + this.width this.maxY = this.y + this.height } set(x, y, width, height) { this.x = x || 0 this.y = y || 0 this.width = width || 0 this.height = height || 0 this.minX = this.x this.minY = this.y this.maxX = this.x + this.width this.maxY = this.y + this.height } position(x, y) { this.x = x this.y = y this.minX = this.x this.minY = this.y this.maxX = this.minX + this.width this.maxY = this.minY + this.height } move(x, y) { this.x += x this.y += y this.minX += x this.minY += y this.maxX += x this.maxY += y } resize(width, height) { this.width = width this.height = height this.minX = this.x this.minY = this.y this.maxX = this.minX + this.width this.maxY = this.minY + this.height } vsAABB(src) { if(this.maxX < src.minX || this.minX > src.maxX) { return false } if(this.maxY < src.minY || this.minY > src.maxY) { return false } return true } vsBorderAABB(src) { if(this.maxX <= src.minX || this.minX >= src.maxX) { return false } if(this.maxY <= src.minY || this.minY >= src.maxY) { return false } return true } vsAABBIntersection(src) { if(this.maxX < src.minX || this.minX > src.maxX) { return 0 } if(this.maxY < src.minY || this.minY > src.maxY) { return 0 } if(this.minX > src.minX || this.minY > src.minY) { return 1 } if(this.maxX < src.maxX || this.maxY < src.maxY) { return 1 } return 2 } vsCircle(circle) { const aabb_halfExtents_width = this.width * 0.5 const aabb_halfExtents_height = this.height * 0.5 const aabb_centerX = this.minX + aabb_halfExtents_width const aabb_centerY = this.minY + aabb_halfExtents_height let diffX = circle.x - aabb_centerX let diffY = circle.y - aabb_centerY diffX = clamp(diffX, -aabb_halfExtents_width, aabb_halfExtents_width) diffY = clamp(diffY, -aabb_halfExtents_height, aabb_halfExtents_height) const closestX = aabb_centerX + diffX const closestY = aabb_centerY + diffY diffX = closestX - circle.x diffY = closestY - circle.y return Math.sqrt((diffX * diffX) + (diffY * diffY)) < circle.radius } vsPoint(x, y) { if(this.minX > x || this.maxX < x) { return false } if(this.minY > y || this.maxY < y) { return false } return true } vsBorderPoint(x, y) { if(this.minX >= x || this.maxX <= x) { return false } if(this.minY >= y || this.maxY <= y) { return false } return true } getSqrDistance(x, y) { let tmp let sqDist = 0 if(x < this.minX) { tmp = (this.minX - x) sqDist += tmp * tmp } if(x > this.maxX) { tmp = (x - this.maxX) sqDist += tmp * tmp } if(y < this.minY) { tmp = (this.minY - y) sqDist += tmp * tmp } if(y > this.maxY) { tmp = (y - this.maxY) sqDist += tmp * tmp } return sqDist } getDistanceVsAABB(aabb) { const centerX = this.minX + ((this.maxX - this.minX) / 2) const centerY = this.minY + ((this.maxY - this.minY) / 2) const srcCenterX = aabb.minX + ((aabb.maxY - aabb.minY) / 2) const srcCenterY = aabb.minY + ((aabb.maxY - aabb.minY) / 2) const diffX = srcCenterX - centerX const diffY = srcCenterY - centerY return Math.sqrt((diffX * diffX) + (diffY * diffY)) } isUndefined() { return (this.maxY === undefined) } print(str) { if(str) { console.log("(AABB) " + str + " minX: " + this.minX + " minY: " + this.minY + " maxX: " + this.maxX + " maxY: " + this.maxY) } else { console.log("(AABB) minX: " + this.minX + " minY: " + this.minY + " maxX: " + this.maxX + " maxY: " + this.maxY) } } } export default AABB