A simulation of a Paul trap.
Last active
July 7, 2020 20:18
-
-
Save mathdoodle/920edc41585eebe3a230ee5843477ef5 to your computer and use it in GitHub Desktop.
Paul trap
This file contains hidden or 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
<!doctype html> | |
<html> | |
<head> | |
<!-- STYLES-MARKER --> | |
<style> | |
/* STYLE-MARKER */ | |
</style> | |
<script src="https://jspm.io/system.js"></script> | |
<!-- SHADERS-MARKER --> | |
<!-- SCRIPTS-MARKER --> | |
</head> | |
<body> | |
<canvas id='canvas'></canvas> | |
<script> | |
// CODE-MARKER | |
</script> | |
<script> | |
System.defaultJSExtensions = true | |
System.import('./index') | |
</script> | |
</body> | |
</html> |
This file contains hidden or 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
import { Geometric3 } from 'davinci-eight' | |
import { VectorE3, BivectorE3 } from 'davinci-eight' | |
import { Engine, Capability, Scene, Facet, PerspectiveCamera } from 'davinci-eight' | |
import { DirectionalLight, TrackballControls } from 'davinci-eight' | |
import { Arrow, Sphere, Color, Grid } from 'davinci-eight' | |
const e1 = Geometric3.e1() | |
const e2 = Geometric3.e2() | |
const e3 = Geometric3.e3() | |
const I = e1 ^ e2 ^ e3 | |
const g = -e3 | |
/** | |
* The position of the particle on the surface. | |
* We will have to move the ball to make it look like it is resting on the surface. | |
*/ | |
const tangent = function(X: VectorE3): BivectorE3 { | |
const x = X.x | |
const y = X.y | |
const v1 = e1 + 2 * x * e3 | |
const v2 = e2 - 2 * y * e3 | |
return (v1 ^ v2).normalize() | |
} | |
const aPosition = (x: number, y: number) => x * e1 + y * e2 + (x * x - y * y) * e3 | |
const aNormal = function(x: number, y: number): Geometric3 { | |
return (I * Geometric3.fromBivector(tangent({ x, y, z: 0 }))).scale(-1).normalize() | |
} | |
const ballCenter = function(X: VectorE3, radius: number): Geometric3 { | |
const P = aPosition(X.x, X.y) | |
const N = aNormal(X.x, X.y) | |
return Geometric3.fromVector(P).add(N, radius) | |
} | |
const ballNormal = function(X: VectorE3) { | |
return aNormal(X.x, X.y) | |
} | |
const acceleration = function(X: VectorE3): VectorE3 { | |
const B = Geometric3.fromBivector(tangent(X)) | |
const c = g << B | |
return B * c | |
} | |
/** | |
* Wrapper around the WebGLRenderingContext providing the ContextManager interface. | |
*/ | |
const engine = new Engine('canvas') | |
.size(500, 500) | |
.clearColor(0.1, 0.1, 0.1, 1.0) | |
.enable(Capability.DEPTH_TEST) | |
/** | |
* A collection of objects that can be rendered with a single draw method call. | |
*/ | |
const scene = new Scene(engine) | |
/** | |
* Rendering information that applies to all objects. | |
*/ | |
const ambients: Facet[] = [] | |
/** | |
* Provides the viewing point and perspective transformation. | |
*/ | |
const camera = new PerspectiveCamera() | |
camera.eye.copy(e3 + e2 + e1).scale(3) | |
camera.up.copy(e3) | |
ambients.push(camera) | |
/** | |
* Provides a light color and direction for Lambert shading. | |
*/ | |
const dirLight = new DirectionalLight() | |
ambients.push(dirLight) | |
/** | |
* Controls the camera by accumulating mouse movements then moving and rotating the camera. | |
*/ | |
const trackball = new TrackballControls(camera, window) | |
trackball.subscribe(engine.canvas) | |
trackball.noPan = true | |
const ball = new Sphere(engine) | |
ball.color = Color.yellow | |
ball.radius = 0.1 | |
scene.add(ball) | |
const grid = new Grid(engine, { | |
mode: 1, | |
aPosition, | |
aNormal | |
}) | |
grid.color = Color.gray | |
scene.add(grid) | |
const arrow = new Arrow(engine) | |
const stats = new Stats() | |
stats.domElement.style.position = 'absolute' | |
stats.domElement.style.top = '10px' | |
stats.domElement.style.left = '10px' | |
stats.domElement.style.zIndex = '100' | |
document.body.appendChild(stats.domElement) | |
const X = ballCenter(0.5 * e2, ball.radius) | |
const T = 5 | |
const ω = 2 * Math.PI / T | |
const B = e1 ^ e2 | |
const R = Geometric3.one() | |
/** | |
* Animates the scene. | |
*/ | |
const animate = function(timestamp: number) { | |
stats.begin() | |
engine.clear() | |
trackball.update() | |
dirLight.direction.copy(camera.look).sub(camera.eye) | |
const t = timestamp * 0.00001 | |
const θ = ω * t | |
R.copy(B).scale(-θ / 2).exp() | |
// grid.R.copy(R) | |
R.copy(B).scale(0.01).exp() | |
X.rotate(R) | |
ball.X.copyVector(ballCenter(X, ball.radius)) | |
arrow.X.copyVector(ballCenter(X, ball.radius)) | |
arrow.vector = ballNormal(X) | |
arrow.color.copy(Color.blue) | |
arrow.render(ambients) | |
arrow.X.copyVector(ballCenter(X, ball.radius)) | |
arrow.vector = acceleration(X) | |
arrow.color.copy(Color.red) | |
arrow.render(ambients) | |
scene.render(ambients) | |
stats.end() | |
requestAnimationFrame(animate) | |
} | |
requestAnimationFrame(animate) |
This file contains hidden or 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
{ | |
"description": "Paul trap", | |
"dependencies": { | |
"stats.js": "0.16.0", | |
"davinci-eight": "7.4.4" | |
}, | |
"operatorOverloading": true, | |
"name": "copy-of-eight-starter-template", | |
"version": "0.1.0", | |
"author": "David Geo Holmes", | |
"linting": true | |
} |
This file contains hidden or 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
body { margin: 0; } | |
canvas { width: 500px; height: 500px } | |
#stats { position: absolute; top: 0; left: 0; } |
This file contains hidden or 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
Show hidden characters
{ | |
"allowJs": true, | |
"checkJs": true, | |
"declaration": true, | |
"emitDecoratorMetadata": true, | |
"experimentalDecorators": true, | |
"jsx": "react", | |
"module": "system", | |
"noImplicitAny": true, | |
"noImplicitReturns": true, | |
"noImplicitThis": true, | |
"noUnusedLocals": true, | |
"noUnusedParameters": true, | |
"preserveConstEnums": true, | |
"removeComments": false, | |
"skipLibCheck": true, | |
"sourceMap": true, | |
"strictNullChecks": true, | |
"suppressImplicitAnyIndexErrors": true, | |
"target": "es5", | |
"traceResolution": true | |
} |
This file contains hidden or 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
{ | |
"rules": { | |
"array-type": [ | |
true, | |
"array" | |
], | |
"curly": false, | |
"comment-format": [ | |
true, | |
"check-space" | |
], | |
"eofline": true, | |
"forin": true, | |
"jsdoc-format": true, | |
"new-parens": true, | |
"no-conditional-assignment": false, | |
"no-consecutive-blank-lines": true, | |
"no-construct": true, | |
"no-for-in-array": true, | |
"no-inferrable-types": [ | |
true | |
], | |
"no-magic-numbers": false, | |
"no-shadowed-variable": true, | |
"no-string-throw": true, | |
"no-trailing-whitespace": [ | |
true, | |
"ignore-jsdoc" | |
], | |
"no-var-keyword": true, | |
"one-variable-per-declaration": [ | |
true, | |
"ignore-for-loop" | |
], | |
"prefer-const": true, | |
"prefer-for-of": true, | |
"prefer-function-over-method": false, | |
"prefer-method-signature": true, | |
"radix": true, | |
"semicolon": [ | |
true, | |
"never" | |
], | |
"trailing-comma": [ | |
true, | |
{ | |
"multiline": "never", | |
"singleline": "never" | |
} | |
], | |
"triple-equals": true, | |
"use-isnan": true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment