[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-users] language-side interpolation?



+
wslib interpolation help file.
josh ugens Interpl class
this functions are clear like water: http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/interpolation/

2011/2/15 LFSaw

I guess you're lost here... only linear interpolation supported:

SequenceableCollection:
       blendAt(floatIndex)     linear
       resamp0(newSize)        no interpol
       resamp1(newSize)        linear (actually using blendAt)

but you can easily write that, I guess :)

regards
       Till

On 15.02.2011, at 08:46, James Harkins wrote:

> Usually I can find what I'm looking for in the class library, or determine pretty quickly that it doesn't exist. In this case, I couldn't find it and I'd be surprised if nobody has done it -- actually, I am surprised that it's not part of the class library.
>
> Any language-side methods to perform cubic interpolation over an array (sequenceable collection)? I'm looking for something that will work on a relatively small array (31 items) and it needs to be synchronous. BufRd will not help in this case.
>
> Seems to me that blend() would benefit from an interpolation-type argument, or have blendCubic etc.
>
> Thanks.
> hjh
>
 
And I made this pretty function to add redundancy:

// 1D interpolations
// based on http://local.wasp.uwa.edu.au/~pbourke/miscellaneous/interpolation
/*
linAt
cosAt
cubAt
herAt
*/

+ SequenceableCollection {
linAt { arg i;
// same as blendAt but less efficient :-)
var y0 = this.at(i.floor);
var y1 = this.at(i.ceil);
var mu = i.frac;
^(y0 * (1 - mu)) + (y1 * mu);
}
cosAt { arg i;
var y0 = this.at(i.floor);
var y1 = this.at(i.ceil);
var mu = i.frac;
var mu1 = (1 - cos(mu * pi)) * 0.5;
^(y0 * (1 - mu1)) + (y1 * mu1);
}
cubAt { arg i, wrap = false;
var x0 = i.floor;
var x1 = i.ceil;
var mu = i.frac;
var mu2 = mu.squared;
var y0, y1, y2, y3;
var a0, a1, a2, a3;
#y0, y1, y2, y3 = this.interpolationYValues(x0, x1, wrap);
a0 = y3 - y2 - y0 + y1;
a1 = y0 - y1 - a0;
a2 = y2 - y0;
a3 = y1;
^(a0 * mu * mu2) + (a1 * mu2) + (a2 * mu) + a3;
}
herAt { arg i, tension = 0, bias = 0, wrap = false;
var x0 = i.floor;
var x1 = i.ceil;
var mu = i.frac;
var y0, y1, y2, y3;
var m0, m1, mu2, mu3;
var a0, a1, a2, a3;
#y0, y1, y2, y3 = this.interpolationYValues(x0, x1, wrap);
mu2 = mu.squared;
mu3 = mu2 * mu;
m0 = (y1 - y0) * (1 + bias) * (1 - tension) * 0.5;
m0 = (y2 - y1) * (1 - bias) * (1 - tension) * 0.5 + m0;
m1 = (y2 - y1) * (1 + bias) * (1 - tension) * 0.5;
m1 = (y3 - y2) * (1 - bias) * (1 - tension) * 0.5 + m1;
a0 = (2 * mu3) - (3 * mu2) + 1;
a1 = mu3 - (2 * mu2) + mu;
a2 = mu3 - mu2;
a3 = (-2 * mu3) + (3 * mu2);
^(a0 * y1) + (a1 * m0) + (a2 * m1) + (a3*y2);
}
interpolationYValues { arg x0, x1, wrap = false;
// private method
var y0, y1, y2, y3;
y1 = this[x0];
y2 = this[x1];
if( wrap ) {
y0 = this.wrapAt(x0 - 1);
y3 = this.wrapAt(x1 + 1);
} {
// keep valid range between 0 and size - 1
if(x0 == (this.size -1) and: { x0 != x1 }) {
Error("Index out of bounds").throw;
};
if((x0 - 1) < 0) {
y0 = this[x0] + slope(y1, y2)
} {
y0 = this[x0 - 1];
};
if((x1 + 1) > (this.size - 1)) {
y3 = this[x1] + slope(y1, y2)
} {
y3 = this[x1 + 1];
};
};
^[y0, y1, y2, y3];
}
slope { arg aNumber, adverb;
^this.performBinaryOp('slope', aNumber, adverb);
}
}

+ SimpleNumber {
slope { arg other;
if( this == other) { ^this - other };
if( this < other ) { ^absdif(this, other) };
if( this > other ) { ^absdif(this, other) * -1 };
}
}

/*
//a = { rrand(-10.0, 10.0) }!10;
//a.plot2("non");

a = [3.5, 1.4, 1.8, 1.3, 3.7, 0, 2.35, 1.6];
a.plot2("non");

r = ((1..70) * 0.1).collect { arg i; a.linAt(i) };
r.plot2("lin");

r = ((1..70) * 0.1).collect { arg i; a.cosAt(i) };
r.plot2("cos");

// hay algo mal?
r = ((1..700) * 0.01).collect { arg i; a.cubAt(i) };
r.plot2("cub");

r = ((1..699) * 0.01).collect { arg i; a.cubAt(i) };
r.plot2("cub");

r = ((1..700) * 0.01).collect { arg i; a.cubAt(i, true) };
r.plot2("cub");

r = ((1..699) * 0.01).collect { arg i; a.herAt(i) };
r.plot2("her");

r = ((1..699) * 0.01).collect { arg i; a.herAt(i, -1, -1) };
x = r.plot2("her");

a.size;
a.cubAt(0.0);
a.cubAt(6.999);
a.cubAt(7);
a.cubAt(7.1);

// 2D ?
//a = [[0, 3.5], [1.1, 1.4], [2, 1.8], [3, 1.3], [4, 3.7], [5, 0], [6, 2.35], [7, 1.6]];
//a.plot2("non");

(
var x = (0..7) * 100;
var y = [3.5, 1.4, 1.8, 1.3, 3.7, 0, 2.35, 1.6] * 100;
var rx = ((1..70) * 0.1).collect { arg i; x.herAt(i, 0, -17) };
var ry = ((1..70) * 0.1).collect { arg i; y.herAt(i, 0, 0) };
var window;

window = Window.new("interp", Rect(0, 0, 700, 400));
window.drawHook = { arg view;
rx.size.do { arg i;
Pen.fillRect(Rect(rx[i], ry[i], 5, 5));
}
};
window.front;
)

[ [1, 2], [2, 4], [2, 5] ].linAt(1.9)
[ [1, 2], [2, 4], [2, 5] ].cubAt(1.9)

(
var a = [[0, 3.5], [1, 1.4], [2, 1.8], [3, 1.3], [4, 3.7], [5, 0], [6, 2.35], [7, 1.6]] * 100;
var ra = ((1..70) * 0.1).collect { arg i; a.herAt(i, 0, [-17, 0]) };
var window;

window = Window.new("interp", Rect(0, 0, 700, 400));
window.drawHook = { arg view;
ra.do { arg i;
Pen.fillRect(Rect(i[0], i[1], 5, 5));
}
};
window.front;
)
*/

best
lucas