Added LowPassFilter and support for smooth scatter rotation and zoom.
This commit is contained in:
+88
-3
@@ -75,7 +75,7 @@ export function sample(population, k) {
|
||||
if (n <= setsize) {
|
||||
// An n-length list is smaller than a k-length set
|
||||
let pool = population.slice()
|
||||
for (let i = 0; i < k; i++) { // invariant: non-selected at [0,n-i)
|
||||
for (let i = 0; i < k; i++) { // inletiant: non-selected at [0,n-i)
|
||||
let j = Math.random() * (n - i) | 0
|
||||
result[i] = pool[j]
|
||||
pool[j] = pool[n - i - 1] // move non-selected item into vacancy
|
||||
@@ -404,8 +404,8 @@ export class Points {
|
||||
|
||||
// Distance == 0.0 indicates an inside relation.
|
||||
static distanceToRect(p, r) {
|
||||
var cx = Math.max(Math.min(p.x, r.x + r.width), r.x)
|
||||
var cy = Math.max(Math.min(p.y, r.y + r.height), r.y)
|
||||
let cx = Math.max(Math.min(p.x, r.x + r.width), r.x)
|
||||
let cy = Math.max(Math.min(p.y, r.y + r.height), r.y)
|
||||
return Math.sqrt((p.x - cx) * (p.x - cx) + (p.y - cy) * (p.y - cy))
|
||||
}
|
||||
|
||||
@@ -968,4 +968,89 @@ export class Strings {
|
||||
}
|
||||
|
||||
|
||||
export class LowPassFilter {
|
||||
|
||||
constructor(smoothing = 0.5, bufferMaxSize=10) {
|
||||
this.smoothing = smoothing // must be smaller than 1
|
||||
this.buffer = [] // FIFO queue
|
||||
this.bufferMaxSize = bufferMaxSize
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup buffer with array of values
|
||||
*
|
||||
* @param {array} values
|
||||
* @returns {array}
|
||||
* @access public
|
||||
*/
|
||||
setup(values) {
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
this.__push(values[i])
|
||||
}
|
||||
return this.buffer
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear buffer to prepare for new values.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
clear() {
|
||||
this.buffer = []
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new value to buffer (FIFO queue)
|
||||
*
|
||||
* @param {integer|float} value
|
||||
* @returns {integer|float}
|
||||
* @access private
|
||||
*/
|
||||
__push(value) {
|
||||
let removed = (this.buffer.length === this.bufferMaxSize)
|
||||
? this.buffer.shift()
|
||||
: 0
|
||||
|
||||
this.buffer.push(value)
|
||||
return removed
|
||||
}
|
||||
|
||||
/**
|
||||
* Smooth value from stream
|
||||
*
|
||||
* @param {integer|float} nextValue
|
||||
* @returns {integer|float}
|
||||
* @access public
|
||||
*/
|
||||
next(nextValue) {
|
||||
|
||||
// push new value to the end, and remove oldest one
|
||||
let removed = this.__push(nextValue)
|
||||
// smooth value using all values from buffer
|
||||
let result = this.buffer.reduce((last, current) => {
|
||||
return this.smoothing * current + (1 - this.smoothing) * last
|
||||
}, removed)
|
||||
// replace smoothed value
|
||||
this.buffer[this.buffer.length - 1] = result
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Smooth array of values
|
||||
*
|
||||
* @param {array} values
|
||||
* @returns {undefined}
|
||||
* @access public
|
||||
*/
|
||||
smoothArray(values) {
|
||||
let value = values[0]
|
||||
for (let i = 1; i < values.length; i++) {
|
||||
let currentValue = values[i]
|
||||
value += (currentValue - value) * this.smoothing
|
||||
values[i] = Math.round(value)
|
||||
}
|
||||
return values
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user