202 lines
5.6 KiB
JavaScript
202 lines
5.6 KiB
JavaScript
var Hermite = {};
|
|
|
|
Hermite.Polynom = function(t, f, fp) {
|
|
this.times = t;
|
|
this.evals = f;
|
|
this.primes = fp;
|
|
|
|
this.baseFunctions = new Array();
|
|
|
|
for (var i in this.times) {
|
|
this.baseFunctions.push(new Hermite.BaseFunction(i, this.times));
|
|
}
|
|
|
|
// Let's do something at least a little reusable
|
|
this.tools = {};
|
|
if (f[0] instanceof THREE.Vector3) {
|
|
this.tools.whatType = 'THREE.Vector3';
|
|
this.tools.sum = Tools.sum;
|
|
this.tools.prod = Tools.mul;
|
|
} else {
|
|
this.tools.whatType = 'number';
|
|
this.tools.sum = function(a, b) { return a + b; };
|
|
this.tools.prod = function(a, b) { return a * b; };
|
|
}
|
|
}
|
|
|
|
Hermite.Polynom.prototype.eval = function(t) {
|
|
var ret;
|
|
|
|
if (this.tools.whatType === 'THREE.Vector3') {
|
|
ret = new THREE.Vector3();
|
|
} else {
|
|
ret = 0;
|
|
}
|
|
|
|
for (var i in this.times) {
|
|
var ti = this.times[i];
|
|
var qi_t = this.baseFunctions[i].eval(t);
|
|
// var qi_ti = this.baseFunctions[i].eval(ti);
|
|
|
|
var qip_ti = this.baseFunctions[i].prime(ti);
|
|
var f_ti = this.evals[i];
|
|
var fp_ti = this.primes[i];
|
|
|
|
// This is the wikipedia formula
|
|
// ret += (qi_t / qi_ti) * ((1 - (t - ti) * (qip_ti / qi_ti)) * f_ti + (t - ti) * fp_ti);
|
|
// Let's not forget that qi_ti = 1
|
|
|
|
// This is the final formula
|
|
// ret += (qi_t) * ((1 - (t - ti) * (qip_ti)) * f_ti + (t - ti) * fp_ti);
|
|
|
|
// This is the implementation working with THREE.Vector3
|
|
// In terms of disgusting code, we're quite good there
|
|
ret =
|
|
this.tools.sum(
|
|
ret,
|
|
this.tools.prod(
|
|
this.tools.sum(
|
|
this.tools.prod(f_ti, 1 - (t - ti) * (qip_ti)),
|
|
this.tools.prod(fp_ti, t - ti)
|
|
),
|
|
qi_t
|
|
)
|
|
);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Hermite.Polynom.prototype.prime = function(t) {
|
|
var ret;
|
|
|
|
if (this.tools.whatType === 'THREE.Vector3') {
|
|
ret = new THREE.Vector3();
|
|
} else {
|
|
ret = 0;
|
|
}
|
|
|
|
for (var i in this.times) {
|
|
var ti = this.times[i];
|
|
var qi_t = this.baseFunctions[i].eval(t);
|
|
// var qi_ti = this.baseFunctions[i].eval(ti);
|
|
|
|
var qip_t = this.baseFunctions[i].prime(t );
|
|
var qip_ti = this.baseFunctions[i].prime(ti);
|
|
var f_ti = this.evals[i];
|
|
var fp_ti = this.primes[i];
|
|
|
|
// The return of the disgusting code...
|
|
// First part is the same that the eval function, but changing qi_t by qip_t
|
|
// (first part of the derivative)
|
|
ret =
|
|
this.tools.sum(
|
|
ret,
|
|
this.tools.prod(
|
|
this.tools.sum(
|
|
this.tools.prod(f_ti, 1 - (t - ti) * (qip_ti)),
|
|
this.tools.prod(fp_ti, t - ti)
|
|
),
|
|
qip_t
|
|
)
|
|
);
|
|
|
|
// Here, we just add
|
|
// ret += qi_t * (-qip_t * f_ti + fp_ti);
|
|
ret =
|
|
this.tools.sum(
|
|
ret,
|
|
this.tools.prod(
|
|
this.tools.sum(
|
|
this.tools.prod(
|
|
f_ti,
|
|
-qip_t
|
|
),
|
|
fp_ti
|
|
),
|
|
qi_t
|
|
)
|
|
);
|
|
|
|
// Now the following code is the same as the precedent affectation
|
|
// However it doesn't work, and I can't see the difference between
|
|
// this and the previous one... so I keep it here, to find the
|
|
// mistate later
|
|
// ret =
|
|
// this.tools.sum(
|
|
// ret,
|
|
// this.tools.prod(
|
|
// this.tools.sum(
|
|
// fp_ti,
|
|
// this.tools.prod(
|
|
// f_ti,
|
|
// -qip_ti
|
|
// )
|
|
// ),
|
|
// qi_t
|
|
// )
|
|
// );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
Hermite.BaseFunction = function(index, times) {
|
|
this.index = index;
|
|
this.times = times;
|
|
}
|
|
|
|
Hermite.BaseFunction.prototype.eval = function(t) {
|
|
var ret = 1;
|
|
|
|
for (var i in this.times) {
|
|
if (i !== this.index) {
|
|
ret *= (t - this.times[i]) / (this.times[this.index] - this.times[i]);
|
|
}
|
|
}
|
|
|
|
return ret * ret;
|
|
}
|
|
|
|
Hermite.BaseFunction.prototype.prime = function(t) {
|
|
var ret = 0;
|
|
|
|
for (var i in this.times) {
|
|
if (i !== this.index) {
|
|
ret += 2 / (t - this.times[i]);
|
|
}
|
|
}
|
|
|
|
return this.eval(t) * ret;
|
|
}
|
|
|
|
Hermite.special = {};
|
|
|
|
// This polynom interpolates with two coords and one derivative
|
|
// t = [0,1]
|
|
Hermite.special.Polynom = function(P0, P1, PP1) {
|
|
this.tools = {};
|
|
if (P0 instanceof THREE.Vector3) {
|
|
this.tools.sum = Tools.sum;
|
|
this.tools.mul = Tools.mul;
|
|
this.tools.diff = Tools.diff;
|
|
this.c = P0.clone();
|
|
} else {
|
|
this.tools.sum = function(a,b) { return a+b; };
|
|
this.tools.mul = function(a,b) { return a*b; };
|
|
this.tools.diff = function(a,b) { return a-b; };
|
|
this.c = P0;
|
|
}
|
|
|
|
this.a = this.tools.sum(PP1, this.tools.diff(P0, P1));
|
|
this.b = this.tools.diff(this.tools.mul(this.tools.diff(P1,P0), 2), PP1);
|
|
}
|
|
|
|
Hermite.special.Polynom.prototype.eval = function(t) {
|
|
return this.tools.sum(this.tools.mul(this.a, t*t), this.tools.sum(this.tools.mul(this.b, t), this.c));
|
|
}
|
|
|
|
Hermite.special.Polynom.prototype.prime = function(t) {
|
|
return this.tools.sum(this.tools.mul(this.a,2*t), this.b);
|
|
}
|