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);
 | |
| }
 |