From 848587f11bef40bec283ecaf2a37834c1643afc6 Mon Sep 17 00:00:00 2001 From: Thomas FORGIONE Date: Tue, 14 Apr 2015 12:02:35 +0200 Subject: [PATCH] Added Hermite functions --- HermiteTest/index.html | 7 ++ HermiteTest/index.py | 28 ++++++ HermiteTest/js/HermiteTest.js | 44 +++++++++ js/Hermite.js | 171 ++++++++++++++++++++++++++++++++++ templates/jsIncludes.html | 1 + 5 files changed, 251 insertions(+) create mode 100644 HermiteTest/index.html create mode 100755 HermiteTest/index.py create mode 100644 HermiteTest/js/HermiteTest.js create mode 100644 js/Hermite.js diff --git a/HermiteTest/index.html b/HermiteTest/index.html new file mode 100644 index 0000000..de5e12e --- /dev/null +++ b/HermiteTest/index.html @@ -0,0 +1,7 @@ +
+

Hermite test

+ +
+
+# +
diff --git a/HermiteTest/index.py b/HermiteTest/index.py new file mode 100755 index 0000000..f3cc931 --- /dev/null +++ b/HermiteTest/index.py @@ -0,0 +1,28 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import sys +from webtools import Web + +def main(): + print('Content-type: text/html') + print() + + page = Web.Element(Web.ROOT_DIR + 'templates/page.html') + head = Web.Element(Web.ROOT_DIR + 'templates/head.html') + body = Web.Element(Web.ROOT_DIR + 'templates/body.html') + jsIncludes = Web.Element(Web.ROOT_DIR + 'templates/jsIncludes.html') + mainJs = Web.Element() + mainJs.open_string = ' ' + content = Web.Element('index.html') + + page.add_child(head) + page.add_child(body) + body.add_child(content) + body.add_child(jsIncludes) + jsIncludes.add_child(mainJs) + + page.print() + +if __name__ == '__main__': + main() diff --git a/HermiteTest/js/HermiteTest.js b/HermiteTest/js/HermiteTest.js new file mode 100644 index 0000000..48daad5 --- /dev/null +++ b/HermiteTest/js/HermiteTest.js @@ -0,0 +1,44 @@ +var container = document.getElementById('content'); + +function print(text) { + var content = document.createTextNode(text); + var new_line = document.createElement('br'); + container.appendChild(content); + container.appendChild(new_line); +} + +function toString(variable) { + if (variable instanceof THREE.Vector3) { + return variable.x + ', ' + variable.y + ', ' + variable.z; + } else { + return variable; + } +} + +// Test with THREE.Vector3 +t = [0,1]; +f = [new THREE.Vector3(0,0,0), new THREE.Vector3(1,1,1)]; +fp = [new THREE.Vector3(0,1,2), new THREE.Vector3(0,0,0)]; + +// Test with doubles +// t = [0,1]; +// f = [0,1]; +// fp = [-1,-1]0; + +var hermite = new Hermite.Polynom(t, f, fp); + +print('M = ['); +for (var t = 0; t < 1; t += 0.01) { + var res = hermite.eval(t); + print(t + ',' + toString(res) + ';'); +} +print('];'); + +print('MP = ['); +for (var t = 0; t < 1; t += 0.01) { + var res = hermite.prime(t); + print(t + ',' + toString(res) + ';'); +} +print('];'); + + diff --git a/js/Hermite.js b/js/Hermite.js new file mode 100644 index 0000000..4bb58f6 --- /dev/null +++ b/js/Hermite.js @@ -0,0 +1,171 @@ +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; +} diff --git a/templates/jsIncludes.html b/templates/jsIncludes.html index aabfb1c..331c761 100644 --- a/templates/jsIncludes.html +++ b/templates/jsIncludes.html @@ -13,4 +13,5 @@ + #