Skip to content

Instantly share code, notes, and snippets.

@mathdoodle
Created November 1, 2016 02:36
Show Gist options
  • Save mathdoodle/deacdb9af50e5007863aa9028f9249f1 to your computer and use it in GitHub Desktop.
Save mathdoodle/deacdb9af50e5007863aa9028f9249f1 to your computer and use it in GitHub Desktop.
Motion Diagram 3D

Motion Diagram 3D

<!doctype html>
<html>
<head>
<!-- STYLES-MARKER -->
<style>
/* STYLE-MARKER */
</style>
<script src="https://jspm.io/system.js"></script>
<!-- SCRIPTS-MARKER -->
</head>
<body>
<canvas id='canvas3D' width='500' height='500'></canvas>
<canvas id='canvas2D' width='500' height='500'></canvas>
<script>
// CODE-MARKER
</script>
<script>
System.import('./index.js')
</script>
</body>
</html>
import {e1, e2, e3} from './math'
const engine = new EIGHT.Engine('canvas3D')
.size(500, 500)
.clearColor(0.1, 0.1, 0.1, 1.0)
// .enable(EIGHT.Capability.DEPTH_TEST)
.enable(EIGHT.Capability.BLEND)
.blendFunc(EIGHT.BlendingFactorSrc.SRC_ALPHA, EIGHT.BlendingFactorDest.ONE);
const ambients: EIGHT.Facet[] = []
const camera = new EIGHT.PerspectiveCamera()
camera.eye.copy(e3-e2).normalize().scale(15)
camera.up.copy(e3)
ambients.push(camera)
const dirLight = new EIGHT.DirectionalLight()
ambients.push(dirLight)
const trackball = new EIGHT.TrackballControls(camera, window)
// Workaround because Trackball no longer supports context menu for panning.
trackball.noPan = true
trackball.subscribe(engine.canvas)
const plane = new EIGHT.Box()
plane.color = EIGHT.Color.blue
plane.width = 8
plane.height = 8
plane.depth = 0.01
plane.opacity = 0.2
plane.subscribe(engine, true)
const sphere = new EIGHT.Sphere()
sphere.radius = 0.1
sphere.color = EIGHT.Color.red
sphere.subscribe(engine, true)
const arrow = new EIGHT.Arrow()
arrow.subscribe(engine, true)
const grid = new EIGHT.GridXY({xMin: -4, xMax: 4, yMin:-4, yMax: 4})
grid.subscribe(engine, true)
const overlay = new EIGHT.Diagram3D('canvas2D', camera)
const resize = windowResize(engine, camera, overlay).resize()
const stats = new Stats()
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
stats.domElement.style.zIndex = '100';
// document.body.appendChild(stats.domElement)
/**
* Animates the scene.
*/
function animate(timestamp: number) {
stats.begin()
engine.clear()
overlay.clear()
trackball.update()
dirLight.direction.copy(camera.look).sub(camera.eye)
// Ordering is important to get the blending effect.
// Render the transparent objects last.
grid.render(ambients)
for (let t = 0; t < 10; t++) {
sphere.X = X(t)
sphere.X.z = t / 2
sphere.render(ambients)
arrow.X = sphere.X
arrow.color = EIGHT.Color.yellow
arrow.h = 5 * V(t)
arrow.render(ambients)
// grid.X.z = t / 2
// grid.render(ambients)
plane.X.z = t / 2
plane.render(ambients)
overlay.fillText(`v = ${arrow.h.toFixed(1)}`, sphere.X + arrow.h)
overlay.fillText(`t = ${t}`, plane.X - 4 * e2 - 2 * e1)
}
stats.end()
requestAnimationFrame(animate)
}
requestAnimationFrame(animate)
function X(t: number): EIGHT.Geometric3 {
return 0.02 * t * t * e1
}
function V(t: number): EIGHT.Geometric3 {
const dt = 0.001
return (X(t + dt) - X(t)).divByScalar(dt)
}
function windowResize(engine: EIGHT.Engine, camera: {aspect: number}, overlay: EIGHT.Diagram3D){
const callback = function() {
engine.size(window.innerWidth, window.innerHeight);
engine.canvas.style.width = `${window.innerWidth}px`
engine.canvas.style.height = `${window.innerHeight}px`
camera.aspect = window.innerWidth / window.innerHeight;
overlay.canvas.width = window.innerWidth
overlay.canvas.height = window.innerHeight
overlay.canvas.style.width = `${window.innerWidth}px`
overlay.canvas.style.height = `${window.innerHeight}px`
const ctxt = overlay.canvas.getContext('2d')
ctxt.font = "20px Arial"
ctxt.fillStyle = '#ffffff'
}
window.addEventListener('resize', callback, false);
const that = {
/**
*
*/
resize: function() {
callback();
return that;
},
/**
* Stop watching window resize
*/
stop : function() {
window.removeEventListener('resize', callback);
return that;
}
};
return that;
}
window.onunload = function() {
// resize.stop()
console.log("Goodbye!")
}
//
// Basis elements
//
export const zero = EIGHT.Geometric3.zero()
export const one = EIGHT.Geometric3.one()
export const e1 = EIGHT.Geometric3.e1()
export const e2 = EIGHT.Geometric3.e2()
export const e3 = EIGHT.Geometric3.e3()
/**
* The pseudoscalar for Euclidean 3D Geometric Space.
*/
const I = e1 ^ e2 ^ e3
//
// Universal functions
//
export const exp = EIGHT.exp
export const log = EIGHT.log
export const cos = EIGHT.cos
export const sin = EIGHT.sin
//
// Constants
//
/**
* A complete turn, 2 * π.
*/
export const τ = 2 * Math.PI
{
"description": "Motion Diagram 3D",
"dependencies": {
"davinci-eight": "2.317.0",
"stats.js": "0.16.0"
},
"operatorOverloading": true,
"name": "motion-diagram",
"version": "0.1.0",
"keywords": [
"WebGL",
"EIGHT",
"Transparency",
"Alpha",
"Blending",
"BLEND",
"SRC_ALPHA",
"DEPTH_TEST"
],
"author": "David Geo Holmes"
}
body {
margin: 0;
overflow: hidden;
}
#canvas3D {
width: 500px;
height: 500px;
}
#canvas2D {
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
width: 500px;
height: 500px;
/**
* Allow events to go to the other elements
*/
pointer-events: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment