Updated with fixes from @pcalessio - uses Math.PI, and fixed norm and dot functions.