Instantly share code, notes, and snippets.

# denisemauldin/.block

Last active October 4, 2017 21:08
Star You must be signed in to star a gist
globe with Inertia dragging with versor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

Add inertia issue #27 to versor rotation of the globe.

Includes a modified versor.js, allowing the multiplication of the final rotation by a delta to the power alpha.

Original research by Philippe Rivière for visionscarto.net.

forked from Fil's block: Inertia dragging with versor

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters

This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
 // Version 0.0.0. Copyright 2017 Mike Bostock. (function(global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.versor = factory()); }(this, (function() {'use strict'; var acos = Math.acos, asin = Math.asin, atan2 = Math.atan2, cos = Math.cos, max = Math.max, min = Math.min, PI = Math.PI, sin = Math.sin, sqrt = Math.sqrt, radians = PI / 180, degrees = 180 / PI; // Returns the unit quaternion for the given Euler rotation angles [λ, φ, γ]. function versor(e) { var l = e[0] / 2 * radians, sl = sin(l), cl = cos(l), // λ / 2 p = e[1] / 2 * radians, sp = sin(p), cp = cos(p), // φ / 2 g = e[2] / 2 * radians, sg = sin(g), cg = cos(g); // γ / 2 return [ cl * cp * cg + sl * sp * sg, sl * cp * cg - cl * sp * sg, cl * sp * cg + sl * cp * sg, cl * cp * sg - sl * sp * cg ]; } // Returns Cartesian coordinates [x, y, z] given spherical coordinates [λ, φ]. versor.cartesian = function(e) { var l = e[0] * radians, p = e[1] * radians, cp = cos(p); return [cp * cos(l), cp * sin(l), sin(p)]; }; // Returns the Euler rotation angles [λ, φ, γ] for the given quaternion. versor.rotation = function(q) { return [ atan2(2 * (q[0] * q[1] + q[2] * q[3]), 1 - 2 * (q[1] * q[1] + q[2] * q[2])) * degrees, asin(max(-1, min(1, 2 * (q[0] * q[2] - q[3] * q[1])))) * degrees, atan2(2 * (q[0] * q[3] + q[1] * q[2]), 1 - 2 * (q[2] * q[2] + q[3] * q[3])) * degrees ]; }; // Returns the quaternion to rotate between two cartesian points on the sphere. versor.delta = function(v0, v1, alpha = 1) { var w = cross(v0, v1), l = sqrt(dot(w, w)); if (!l) return [1, 0, 0, 0]; var t = alpha * acos(max(-1, min(1, dot(v0, v1)))) / 2, s = sin(t); // t = θ / 2 return [cos(t), w[2] / l * s, -w[1] / l * s, w[0] / l * s]; }; // Returns the quaternion that represents q0 * q1. versor.multiply = function(q0, q1) { return [ q0[0] * q1[0] - q0[1] * q1[1] - q0[2] * q1[2] - q0[3] * q1[3], q0[1] * q1[0] + q0[0] * q1[1] + q0[2] * q1[3] - q0[3] * q1[2], q0[0] * q1[2] - q0[1] * q1[3] + q0[2] * q1[0] + q0[3] * q1[1], q0[0] * q1[3] + q0[1] * q1[2] - q0[2] * q1[1] + q0[3] * q1[0] ]; }; function cross(v0, v1) { return [ v0[1] * v1[2] - v0[2] * v1[1], v0[2] * v1[0] - v0[0] * v1[2], v0[0] * v1[1] - v0[1] * v1[0] ]; } function dot(v0, v1) { return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2]; } return versor; })));
to join this conversation on GitHub. Already have an account? Sign in to comment