Snippets

Benjamin J. DeLong Interpolations

Created by Benjamin J. DeLong last modified
function linearList (min, max, len) {
    var interpolated = [];
    var range = max - min;
    var diff = range / (len - 1);
    var value = +min;
    for (var i = 0; i < len; i++) {
        interpolated.push(value);
        value += diff;
    }
    return interpolated;
}
/*

Interpolate constructor

With properties for the expected min/max outputs

Usage:

> translate = new Interpolate();
> val = translate.from(0, 5).to(0, 100).val(2.5);
> console.assert(val === 50);

*/
function Interpolate () {
	this.input_from = null;
	this.input_to = null;
	this.output_from = null;
	this.output_to = null;
	this.output_min = null;
	this.output_max = null;
}

Interpolate.prototype.from = function (min, max) {
	/*
	
	x values (input range)

	*/
	this.input_from = Number( min );
	this.input_to = Number( max );
	return this;
};

Interpolate.prototype.to = function (_min, _max) {
	/*

	y values (desired output range)

	*/
	var min = Number( _min ),
		max = Number( _max );
	this.output_from = min;
	this.output_to = max;
	this.output_min = Math.min(min, max);
	this.output_max = Math.max(min, max);
	return this;
};

Interpolate.prototype.checkBounds = function (output) {
	/*

	check if value is between max/min

	*/
	if (output > this.output_max) {
		return this.output_max;
	} 

	if (output < this.output_min) {
	    return this.output_min;
	}

	return output;
};

Interpolate.prototype.linear = function (val) {
	var output = (val - this.input_from) / 
		(this.input_to - this.input_from) * 
		(this.output_to - this.output_from) + 
		this.output_from;

    return this.checkBounds( output );
};

Interpolate.prototype.exponential = function (val) {
	/*
	exponential rise
	y = ab^x
	*/
	var offset = 0,
		a = this.output_from,
		y2 = this.output_to,
		x2 = this.input_to - this.input_from,
		b,
		output;

	if (val === this.input_to) {
		return this.output_to;
	}

	if (val === this.input_from) {
		return this.output_from;
	}

	// x is an index (starts at 0)
	val -= this.input_from;

	if (a <= 0 || y2 <= 0) {
		// can't have y = 0 or less for pow functions
		offset = Math.abs(Math.min(a, y2)) + 1;
		a += offset;
		y2 += offset;
	}

	// I don't remember why I did this - BJD
	// however, b is supposed to equal y
	// when x == 0; so apparently this 
	// is a formula to find that
	b = Math.pow(y2 / a, 1 / x2);

	// formula here (reapply offset to deal with 0's)
	output = a * Math.pow(b, val) - offset;

    return this.checkBounds( output );
};

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.