Skip to content

Instantly share code, notes, and snippets.

@mathdoodle
Last active August 29, 2015 14:22
Show Gist options
  • Save mathdoodle/3355e5ed04008659ca7d to your computer and use it in GitHub Desktop.
Save mathdoodle/3355e5ed04008659ca7d to your computer and use it in GitHub Desktop.
MathBox Slideshow
{
"uuid": "6ba2243b-b81a-454c-94bb-fdffcbeb72b1",
"description": "MathBox Slideshow",
"dependencies": {
"DomReady": "latest",
"davinci-mathbox": "latest",
"davinci-blade": "1.1.1"
},
"operatorOverloading": true
}
<!doctype html>
<html>
<head>
<style>
/* STYLE-MARKER */
</style>
<!-- SCRIPTS-MARKER -->
<script>
// CODE-MARKER
</script>
</head>
<body>
<div id="info" class="transition">Use the <kbd>←</kbd><kbd>→</kbd> keys to step through.</div>
</body>
</html>
DomReady.ready(function() {
ThreeBox.preload([
'../shaders/MathBox.glsl.html'
], function(assets) {
main(assets);
});});
var TAU = Math.PI * 2;
var HALF_TURN = Math.PI;
var QUARTER_TURN = Math.PI / 2;
var EIGHTH_TURN = Math.PI / 4;
/**
* Normalize angle so that it conforms to usual spherical coordinate conventions.
*/
function phi(angle: number): number {
return -angle;
}
/**
*
*/
function theta(angle: number): number {
return Math.PI/2 -angle;
}
function main(assets) {
// MathBox boilerplate.
var stage: MathBox.Stage = mathBox({
cameraControls: false,
cursor: true,
controlClass: ThreeBox.OrbitControls,
elementResize: true,
fullscreen: true,
screenshot: true,
stats: false,
scale: 1
}).start();
// Viewport and camera setup.
stage
// Euler rotation of negative quarter turn about x-axis puts us into a more mathematical perspective.
.viewport({type: 'cartesian',rotation:[-QUARTER_TURN, 0, 0]})
// Unfortunately, theta and phi don't follow normal conventions.
.camera({theta: theta(0), phi: phi(-QUARTER_TURN)})
.transition(300);
// Director
var director = new MathBox.Director(stage, script());
var instant = false;
var delay = 0;
document.getElementById('info').style.opacity = '1';
// Arrow controls
window.addEventListener('touchstart', function (e) {
director.forward();
document.getElementById('info').style.opacity = '0';
});
window.addEventListener('keydown', function (e) {
if (e.keyCode == 38 || e.keyCode == 37) {
director.back(instant, delay);
}
else if (e.keyCode == 40 || e.keyCode == 39) {
director.forward(instant, delay);
}
else {
return;
}
// Hide the information element once the slideshow has started.
document.getElementById('info').style.opacity = '0';
});
// Random access is useful during development.
// director.go(8, false);
}
/**
*
*/
function script(): {}[][][] {
var e1 = blade.vectorE3(1,0,0);
var e2 = blade.vectorE3(0,1,0);
var e3 = blade.vectorE3(0,0,1);
var a = blade.vectorE3(0.2,0.5,0.4);
var ID_AXIS_X = 'axis-x';
var ID_AXIS_Y = 'axis-y';
var ID_AXIS_Z = 'axis-z';
var ID_PLANE_XY = 'plane-xy';
var ID_PLANE_YZ = 'plane-yz';
var ID_PLANE_ZX = 'plane-zx';
var ID_VECTOR_A = 'vector-a';
return [
[
grid(ID_PLANE_XY, [0,1]),
axis(ID_AXIS_X, 0, 0xff0000),
axis(ID_AXIS_Y, 1, 0x00ff00)
],
[
['animate', 'camera', {theta: theta(QUARTER_TURN * 4/5), phi: phi(QUARTER_TURN*1/3)}, {delay: 0, duration:1500}]
],
[
axis(ID_AXIS_Y, 2, 0x0000ff)
],
[
grid(ID_PLANE_ZX, [2, 0]),
],
[
grid(ID_PLANE_YZ, [1, 2]),
],
[
remove(id(ID_PLANE_XY)),
remove(id(ID_PLANE_YZ)),
remove(id(ID_PLANE_ZX))
],
[
['animate', id(ID_AXIS_Z), {color: 0xCCCC00}, {delay: 0, duration:1500}],
['animate', ID_AXIS_Z, {color: 0x00CCCC}, {delay: 0, duration:1500}],
positionVector(ID_VECTOR_A, a)
],
[
lineFromPositionToPlane(a, e1^e2),
lineFromPositionToPlane(a, e2^e3),
lineFromPositionToPlane(a, e3^e1)
]
];
}
function id(name: string): string {
return '#' + name;
}
function axis(id: string, axis: number, color: number): {}[] {
var options: MathBox.AxisOptions = {};
return ['add', 'axis', {id: id, axis: axis, color:color, ticks:0},{duration:1500}]
}
function grid(id: string, axis: number[]): {}[] {
return ['add','grid',{id: id, axis: axis},{duration:1500}];
}
/**
* Adds a position vector ( a vector based at the origin).
*/
function positionVector(id: string, v: {x: number; y: number; z: number}): {}[] {
var options: MathBox.VectorOptions = {};
options.id = id;
options.color = 0xDDDDDD;
options.data = [[0,0,0],[v.x, v.y, v.z]];
return ['add','vector', options];
}
function lineFromPositionToPlane(a: blade.Euclidean3, B: blade.Euclidean3): {}[] {
var options: MathBox.CurveOptions = {};
options.n = 10;
// options.points = true;
// options.pointSize = 4;
options.line = true;
options.lineWidth = 2;
options.color = 0xc0c0c0;
options.expression = function(x: number, index: number) {
var d = projectOntoBivector(a, B);
var e = midpoint(d, a, x);
return [e.x, e.y, e.z]
};
return ['add','curve', options];
}
function projectOntoBivector(v: blade.Euclidean3, B: blade.Euclidean3) {
var unitB = B / B.norm();
var c = v << unitB;
var R = Math.cos(Math.PI/4) + unitB * Math.sin(Math.PI / 4);
return R * c * ~R;
}
function remove(id: string) {
return ['remove', id, {duration:1500}];
}
/**
* Computes a point along a line that runs through a start and finish point.
*/
function midpoint(start: blade.Euclidean3, finish: blade.Euclidean3, f: number): blade.Euclidean3 {
return start + f * (finish - start);
}
// Base plane of surface
function flat(a: number, b: number, x: number, y: number): number[] {
return [a/3, 0.001, b/3];
}
html, body { height: 100%; }
body { margin: 0; padding: 0 }
canvas { display: block }
#info {
position: absolute;
left: 50%;
bottom: 50px;
z-index: 20;
width: 300px;
margin-left: -150px;
padding: 25px;
background: rgba(0, 0, 0, .5);
color: #fff;
font-family: "Lucida Grande", sans-serif;
font-size: 16px;
text-align: center;
border-radius: 3px;
text-shadow: 0px 1px 0px rgba(0, 0, 0, .4);
opacity: 0;
}
#info.transition {
-webkit-transition: opacity 300ms ease-in-out;
-moz-transition: opacity 300ms ease-in-out;
transition: opacity 300ms ease-in-out;
}
#info kbd {
background: #aaa;
box-shadow: 0px 1px 1px rgba(0, 0, 0, .3);
border-radius: 3px;
padding: 3px;
margin: 3px;
font-family: inherit;
}
.mathbox-label {
font-family: 'klavika-web', sans-serif;
font-weight: normal;
font-style: normal;
text-shadow:
3px 0px 1px rgb(255, 255, 255),
-3px 0px 1px rgb(255, 255, 255),
0px -3px 1px rgb(255, 255, 255),
0px 3px 1px rgb(255, 255, 255),
2px 2px 1px rgb(255, 255, 255),
-2px 2px 1px rgb(255, 255, 255),
2px -2px 1px rgb(255, 255, 255),
-2px -2px 1px rgb(255, 255, 255),
3px 2px 1px rgb(255, 255, 255),
-3px 2px 1px rgb(255, 255, 255),
3px -2px 1px rgb(255, 255, 255),
-3px -2px 1px rgb(255, 255, 255),
1px 3px 1px rgb(255, 255, 255),
-1px 3px 1px rgb(255, 255, 255),
1px -3px 1px rgb(255, 255, 255),
-1px -3px 1px rgb(255, 255, 255),
-1px -1px 1px rgb(255, 255, 255),
-1px 1px 1px rgb(255, 255, 255),
1px -1px 1px rgb(255, 255, 255),
1px 1px 1px rgb(255, 255, 255);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment