@midpoint68/pocket
Advanced tools
Comparing version 1.0.1 to 1.0.2
{ | ||
"name": "@midpoint68/pocket", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "A simple and efficient particle manager for JavaScript.", | ||
@@ -5,0 +5,0 @@ "main": "pocket.js", |
@@ -1,6 +0,25 @@ | ||
"use strict"; | ||
/*! | ||
* Copyright (c) Trevor Richard | ||
*/ | ||
class Particle { | ||
MIT License | ||
Copyright (c) 2020 Trevor Richard | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
export class Particle { | ||
constructor({ x, y, z = 0, radius = 0, data }) { | ||
@@ -27,3 +46,7 @@ this.x = x; | ||
throw new Error("Particle radius must be greater than zero."); | ||
this.radius = radius; | ||
if (this.pocket && this.subPocket) { | ||
this.subPocket.retrieve(this); | ||
this.radius = radius; | ||
this.pocket.put(this); | ||
} | ||
return radius; | ||
@@ -37,3 +60,3 @@ } | ||
} | ||
class SubPocket { | ||
export class SubPocket { | ||
constructor({ parent, radius, position }) { | ||
@@ -79,3 +102,3 @@ this.parent = parent; | ||
retrieve(p) { | ||
this.particles = this.particles.filter(p => p != p); | ||
this.particles = this.particles.filter(pp => pp != p); | ||
if (this.pockets.length == 0 && this.particles.length == 0) { | ||
@@ -92,5 +115,5 @@ this.parent.remove(this); | ||
} | ||
search(radius, center) { | ||
var found = new Array(); | ||
const diff = Pocket.Tools.sub(this.position, center); | ||
search(radius, center, set, transform) { | ||
const pos = transform ? transform(this.position) : this.position; | ||
const diff = Pocket.Tools.sub(pos, center); | ||
const dist = Pocket.Tools.mag(diff); | ||
@@ -100,16 +123,17 @@ if (dist - radius < this.radius) { | ||
const p = this.particles[i]; | ||
const p_diff = Pocket.Tools.sub(p, center); | ||
const p_pos = transform ? transform(p) : p; | ||
const p_diff = Pocket.Tools.sub(p_pos, center); | ||
const p_dist = Pocket.Tools.mag(p_diff); | ||
if (p_dist - radius < p.radius) { | ||
found.push(p); | ||
set.add(p); | ||
} | ||
} | ||
for (let i = 0; i < this.pockets.length; i++) { | ||
found = found.concat(this.pockets[i].search(radius, center)); | ||
this.pockets[i].search(radius, center, set, transform); | ||
} | ||
} | ||
return found; | ||
return set; | ||
} | ||
} | ||
class Pocket { | ||
export class Pocket { | ||
constructor() { | ||
@@ -162,10 +186,10 @@ this.root = undefined; | ||
} | ||
search(radius, center) { | ||
search(radius, center, transform) { | ||
if (!center.z) | ||
center.z = 0; | ||
if (this.root) { | ||
return this.root.search(radius, center); | ||
return this.root.search(radius, center, new Set(), transform); | ||
} | ||
else { | ||
return new Array(); | ||
return new Set(); | ||
} | ||
@@ -180,10 +204,9 @@ } | ||
for (let r = startRadius; r < this.root.radius * 2; r *= 2) { | ||
const pool = this.root.search(r, position); | ||
if (pool.length > 0) { | ||
let closest = pool[0]; | ||
let dist = Pocket.Tools.mag(Pocket.Tools.sub(closest, position)); | ||
for (let i = 1; i < pool.length; i++) { | ||
const p = pool[i]; | ||
const pool = this.search(r, position); | ||
if (pool.size > 0) { | ||
let closest = undefined; | ||
let dist = undefined; | ||
for (const p of pool) { | ||
const p_dist = Pocket.Tools.mag(Pocket.Tools.sub(p, position)); | ||
if (p_dist < dist) { | ||
if (dist === undefined || p_dist < dist) { | ||
closest = p; | ||
@@ -201,3 +224,3 @@ dist = p_dist; | ||
if (!this.root) | ||
return new Array(); | ||
return new Set(); | ||
return this.search(this.root.radius, this.root.position); | ||
@@ -216,4 +239,11 @@ } | ||
mag: (v) => { | ||
return Math.sqrt(Math.pow(Math.sqrt(v.x * v.x + v.y * v.y), 2) + (v.z || 0) * (v.z || 0)); | ||
return Math.sqrt(v.x * v.x + v.y * v.y + (v.z || 0) * (v.z || 0)); | ||
}, | ||
mul: (v0, v1) => { | ||
return { | ||
x: v0.x * v1.x, | ||
y: v0.y * v1.y, | ||
z: (v0.z || 0) * (v1.z || 0) | ||
}; | ||
} | ||
}; |
/*! | ||
* Copyright (c) Trevor Richard | ||
*/ | ||
MIT License | ||
interface Vector { | ||
Copyright (c) 2020 Trevor Richard | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
export interface Vector { | ||
x: number | ||
@@ -11,3 +31,3 @@ y: number | ||
class Particle<T> implements Vector { | ||
export class Particle<T> implements Vector { | ||
@@ -65,3 +85,7 @@ x: number | ||
if (radius <= 0) throw new Error("Particle radius must be greater than zero."); | ||
this.radius = radius; | ||
if (this.pocket && this.subPocket) { | ||
this.subPocket.retrieve(this); | ||
this.radius = radius; | ||
this.pocket.put(this); | ||
} | ||
return radius; | ||
@@ -80,3 +104,3 @@ } | ||
class SubPocket<T> { | ||
export class SubPocket<T> { | ||
@@ -158,3 +182,3 @@ radius: number | ||
retrieve(p: Particle<T>) { | ||
this.particles = this.particles.filter(p => p != p); | ||
this.particles = this.particles.filter(pp => pp != p); | ||
if (this.pockets.length == 0 && this.particles.length == 0) { | ||
@@ -183,6 +207,7 @@ this.parent.remove(this); | ||
* @param center The 2D or 3D vector coordinates of the center of the search | ||
* @param transform The optional transform function to apply to the particles before checking their inclusion | ||
*/ | ||
search(radius: number, center: Vector) { | ||
var found = new Array<Particle<T>>(); | ||
const diff = Pocket.Tools.sub(this.position, center); | ||
search(radius: number, center: Vector, set: Set<Particle<T>>, transform?: (v: Vector) => Vector) { | ||
const pos = transform ? transform(this.position) : this.position; | ||
const diff = Pocket.Tools.sub(pos, center); | ||
const dist = Pocket.Tools.mag(diff); | ||
@@ -194,6 +219,7 @@ if (dist - radius < this.radius) { | ||
const p = this.particles[i]; | ||
const p_diff = Pocket.Tools.sub(p, center); | ||
const p_pos = transform ? transform(p) : p; | ||
const p_diff = Pocket.Tools.sub(p_pos, center); | ||
const p_dist = Pocket.Tools.mag(p_diff); | ||
if (p_dist - radius < p.radius) { | ||
found.push(p); | ||
set.add(p); | ||
} | ||
@@ -204,7 +230,7 @@ } | ||
for (let i = 0; i < this.pockets.length; i++) { | ||
found = found.concat(this.pockets[i].search(radius, center)); | ||
this.pockets[i].search(radius, center, set, transform); | ||
} | ||
} | ||
return found; | ||
return set; | ||
} | ||
@@ -214,3 +240,3 @@ | ||
class Pocket<T> { | ||
export class Pocket<T> { | ||
@@ -227,3 +253,10 @@ static Tools = { | ||
mag: (v: Vector) => { | ||
return Math.sqrt(Math.pow(Math.sqrt(v.x * v.x + v.y * v.y), 2) + (v.z || 0) * (v.z || 0)); | ||
return Math.sqrt(v.x * v.x + v.y * v.y + (v.z || 0) * (v.z || 0)); | ||
}, | ||
mul: (v0: Vector, v1: Vector) => { | ||
return { | ||
x: v0.x * v1.x, | ||
y: v0.y * v1.y, | ||
z: (v0.z || 0) * (v1.z || 0) | ||
}; | ||
} | ||
@@ -308,9 +341,10 @@ }; | ||
* @param center The 2D or 3D Vector coordinates of the search | ||
* @param transform The optional transform function to apply to the particles before checking their inclusion | ||
*/ | ||
search(radius: number, center: Vector) { | ||
search(radius: number, center: Vector, transform?: (v: Vector) => Vector) { | ||
if (!center.z) center.z = 0; | ||
if (this.root) { | ||
return this.root.search(radius, center); | ||
return this.root.search(radius, center, new Set(), transform); | ||
} else { | ||
return new Array<Particle<T>>(); | ||
return new Set<Particle<T>>(); | ||
} | ||
@@ -329,10 +363,9 @@ } | ||
for (let r = startRadius; r < this.root.radius * 2; r *= 2) { | ||
const pool = this.root.search(r, position); | ||
if (pool.length > 0) { | ||
let closest = pool[0]; | ||
let dist = Pocket.Tools.mag(Pocket.Tools.sub(closest, position)); | ||
for (let i = 1; i < pool.length; i++) { | ||
const p = pool[i]; | ||
const pool = this.search(r, position); | ||
if (pool.size > 0) { | ||
let closest: Particle<T> | undefined = undefined; | ||
let dist: number | undefined = undefined; | ||
for (const p of pool) { | ||
const p_dist = Pocket.Tools.mag(Pocket.Tools.sub(p, position)); | ||
if (p_dist < dist) { | ||
if (dist === undefined || p_dist < dist) { | ||
closest = p; | ||
@@ -342,3 +375,3 @@ dist = p_dist; | ||
} | ||
return closest; | ||
return <Particle<T>>closest; | ||
} | ||
@@ -354,3 +387,3 @@ } | ||
all() { | ||
if (!this.root) return new Array<Particle<T>>(); | ||
if (!this.root) return new Set<Particle<T>>(); | ||
return this.search(this.root.radius, this.root.position); | ||
@@ -360,1 +393,2 @@ } | ||
} | ||
@@ -28,3 +28,3 @@ # Pocket | ||
```javascript | ||
// Get all particles within a 1 unit radius of the point (50, 50, 50) | ||
// Get a Set of all particles within a 1 unit radius of the point (50, 50, 50) | ||
const particles = pocket.search(1, {x: 50, y: 50, z: 50}); | ||
@@ -31,0 +31,0 @@ ``` |
{ | ||
"compilerOptions": { | ||
"module": "none", | ||
"module": "ES6", | ||
"target": "ES6", | ||
@@ -8,8 +8,7 @@ "noImplicitAny": true, | ||
"sourceMap": false, | ||
"outFile": "pocket.js", | ||
"strict": true, | ||
}, | ||
"files": [ | ||
"include": [ | ||
"pocket.ts" | ||
] | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
35292
578