This repository has been archived on 2022-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
dwelibs/src/math.js

170 lines
4.4 KiB
JavaScript

DWE.Math = {}
DWE.Math.random = function (i,j) {
return Math.floor(Math.random() * j) + i
}
DWE.Math.lerp = function (v0, v1, t) {
return (1 - t) * v0 + t * v1
}
DWE.Math.reverseLerp = function (v0, v1, t) {
return 1.0 / ((v1 - v0) * t)
}
DWE.Math.intersectsBox = function (ax, ay, aw, ah, bx, by, bw, bh) {
return (Math.abs(ax - bx) * 2 <= (aw + bw)) &&
(Math.abs(ay - by) * 2 <= (ah + bh))
}
DWE.Math.clamp = function (val, min, max) {
return Math.max(min, Math.min(max, val))
}
// Two-dimensional vector
DWE.Math.Vector2 = class {
constructor (x, y) {
this.x = x
this.y = y
}
get magnitude () {
return Math.abs(Math.sqrt((this.x * this.x) + (this.y * this.y)))
}
normalize () {
var len = this.magnitude
this.x /= len
this.y /= len
return this
}
get isNormal () {
return 1 === Math.floor(this.magnitude)
}
get angle () {
if (!this.isNormal) return NaN
return Math.atan2(this.x, this.y)
}
distance (vec) {
if (!(vec instanceof DWE.Math.Vector2)) throw new Error('Distance function takes another Vector2 as an argument.')
return Math.abs(Math.sqrt(Math.pow(vec.x - this.x, 2) + Math.pow(vec.y - this.y, 2)))
}
add (vec) {
if (!(vec instanceof DWE.Math.Vector2)) throw new Error('Add function takes another Vector2 as an argument.')
this.x += vec.x
this.y += vec.y
return this
}
subtract (vec) {
if (!(vec instanceof DWE.Math.Vector2)) throw new Error('Subtract function takes another Vector2 as an argument.')
this.x -= vec.x
this.y -= vec.y
return this
}
multiply (vec) {
if (typeof vec === 'number' && !isNaN(vec)) {
this.x *= vec
this.y *= vec
return this
}
if (!(vec instanceof DWE.Math.Vector2)) throw new Error('Multiply function takes a Vector2 or Number as an argument.')
this.x *= vec.x
this.y *= vec.y
return this
}
divide (vec) {
if (typeof vec === 'number' && !isNaN(vec)) {
this.x /= vec
this.y /= vec
return this
}
if (!(vec instanceof DWE.Math.Vector2)) throw new Error('Division function takes a Vector2 or Number as an argument.')
this.x /= vec.x
this.y /= vec.y
return this
}
}
// A box.
DWE.Math.Box2 = class Box2 extends DWE.Math.Vector2 {
constructor (x, y, w, h) {
super(x, y)
this.width = w
this.height = h
}
intersectsBox (box) {
if (!(box instanceof DWE.Math.Box2)) throw new Error('Intersection function takes another Box2 as an argument.')
// get the vectors to check against
var vX = (box.x + (box.width / 2)) - (this.x + (this.width / 2))
var vY = (box.y + (box.height / 2)) - (this.y + (this.height / 2))
// add the half widths and half heights of the objects
var hWidths = (box.width / 2) + (this.width / 2)
var hHeights = (box.height / 2) + (this.height / 2)
var colDir = null
// if the x and y vector are less than the half width or half height, they we must be inside the object, causing a collision
// figures out on which side we are colliding (top, bottom, left, or right)
if (Math.abs(vX) < hWidths && Math.abs(vY) < hHeights) {
var oX = hWidths - Math.abs(vX)
var oY = hHeights - Math.abs(vY)
if (oX >= oY) {
if (vY > 0) {
colDir = {dir: 't', y: oY, x: 0}
} else {
colDir = {dir: 'b', y: -oY, x: 0}
}
} else {
if (vX > 0) {
colDir = {dir: 'l', y: 0, x: oX}
} else {
colDir = {dir: 'r', y: 0, x: -oX}
}
}
}
return colDir
}
intersectsCircle (circle) {
if (!(circle instanceof DWE.Math.Circle)) throw new Error('Intersection function takes another Circle as an argument.')
var circleDistance = new DWE.Math.Vector2(Math.abs(circle.x - this.x), Math.abs(circle.y - this.y))
if (circleDistance.x > (this.width/2 + circle.r)) return false
if (circleDistance.y > (this.height/2 + circle.r)) return false
if (circleDistance.x <= (this.width/2)) return true
if (circleDistance.y <= (this.height/2)) return true
var cornerDistance_sq = Math.pow(circleDistance.x - this.width/2, 2) +
Math.pow(circleDistance.y - this.height/2, 2)
return (cornerDistance_sq <= Math.pow(circle.r, 2))
}
}
// A circle.
DWE.Math.Circle = class {
constructor (x, y, r) {
this.x = x
this.y = y
this.r = r
}
get radius () {
return this.r
}
}