Skip to content

Instantly share code, notes, and snippets.

@stemcstudio
Last active August 3, 2016 21:00
Show Gist options
  • Select an option

  • Save stemcstudio/88343d3cb8469917c027d07de5804818 to your computer and use it in GitHub Desktop.

Select an option

Save stemcstudio/88343d3cb8469917c027d07de5804818 to your computer and use it in GitHub Desktop.
Geometric3 in Computational Modeling

Vector Modeling Problem Framework

Overview

This is a starter project for creating Computational Projects for learning geometry, kinematics and dynamics.

A student develops their own Vector3 class for describing the position and velocity of objects in 3D. This class then becomes the basis for future projects. Vector3 is a springboard to Geometric3, a geometric object for Euclidean space using Geometric Algebra.

The Vector3 class in the file Vector3.ts is initially nothing more than a triple of Cartesian coordinates. The goal is to develop the Vector3 class into a mathematical object supporting coordinate-free geometry. The student develops an appreciation of the power of geometric objects for representing physical laws.

Principles

  1. Productivity. The project has been designed so that the student need only work in the index.ts and Vector3.ts files without becoming bogged down in the details of Computer Graphics.
  2. Transparency. The project does not hide details, so that the details may be explored. Explicit is better than implicit.
  3. Constructive Modeling. The important Physical, Mathematical, and Computation models are constructed by the student. We understand that which we construct.
  4. Ownership. The student takes ownership of that which they construct. Errors become challenges to mastery.
  5. Separation. Models should be distinct from graphical representations. Constructing algorithms and data structures is a part of developing Computational Thinking skills.

Instructions

Some ideas:

  1. Use the Vector3 to model position and velocity kinematic variables. Position and move an object in various ways.
  2. Develop methods for implementing scalar multiplication, addition and subtraction.
  3. Replace explicit method calls with operator overloading for a more natural representation of geometric ideas.
  4. Develop methods that provide magnitude and direction.
  5. Define basis vector constants.
  6. Develop methods that implement magnitude and direction.
  7. Develop methods for projection and a scalar product.
  8. Develop methods for reflection and rejection.
  9. Develop method for vector cross-product.
  10. Use the EIGHT.Arrow class for visualizing vectors.
  11. Use the EIGHT.Basis class for visualizing a coordinate basis.
  12. Use EIGHT.Trail for showing a graphical trail.
  13. Use EIGHT.Vector3 and EIGHT.Geometric3 as advanced examples of geometric quantities in 3D
  14. Use the UNITS library for investigating Units of Measure.
  15. Use JSXGraph library for graphing.
  16. Introduce mass, momentum, force, and dynamics.
  17. Model single and multi-particle problems.
  18. Model two-particle problems with internal interactions.
  19. Model rigid-body problems.
  20. Write unit tests to verify Vector3 class.
<!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='my-canvas'></canvas>
<script>
// CODE-MARKER
</script>
<script>
System.import('./index.js')
</script>
</body>
</html>
import World from './World'
/**
* A brave new World.
*/
const world = new World()
const sphere = world.createSphere()
sphere.color = new EIGHT.Color(0.8984, 0.1133, 0.3711)
sphere.radius = 0.3
const gridXY = world.createGridXY({segments: 20, min: -10, max: +10})
gridXY.color = new EIGHT.Color(0.4, 0.4, 0.4)
world.reset()
let r = EIGHT.Geometric3.vector(-10, 0, 0)
let v = EIGHT.Geometric3.vector(1, 0, 0)
const stats = new Stats()
document.body.appendChild(stats.dom)
const animate = function() {
stats.begin()
world.beginFrame()
const Δt = world.running ? 0.05 : 0
if (world.time === 0) {
r = EIGHT.Geometric3.vector(-10, 0, 0)
v = EIGHT.Geometric3.vector(1, 0, 0)
}
world.time = world.time + Δt
r = r + v * Δt
sphere.X.copy(r)
world.draw()
stats.end()
// This call keeps the animation going.
requestAnimationFrame(animate)
}
// This call starts the animation.
requestAnimationFrame(animate)
{
"description": "Geometric3 in Computational Modeling",
"dependencies": {
"DomReady": "1.0.0",
"jasmine": "2.4.1",
"davinci-eight": "2.245.0",
"dat-gui": "0.5.0",
"stats.js": "0.16.0"
},
"name": "copy-of-Vector Modeling Problem Framework",
"version": "0.1.0",
"keywords": [
"EIGHT",
"project",
"Getting",
"Started",
"WebGL"
],
"operatorOverloading": true
}
body {
background-color: white;
}
const origin = EIGHT.Geometric3.vector(0, 0, 0)
const e1 = EIGHT.Geometric3.vector(1, 0, 0)
const e2 = EIGHT.Geometric3.vector(0, 1, 0)
const e3 = EIGHT.Geometric3.vector(0, 0, 1)
export default class World {
private engine: EIGHT.Engine;
private scene: EIGHT.Scene;
private ambients: EIGHT.Facet[] = [];
private camera: EIGHT.PerspectiveCamera;
private trackball: EIGHT.TrackballControls;
private dirLight: EIGHT.DirectionalLight;
private gui: dat.GUI;
/**
* An flag that determines whether the simulation should move forward.
*/
public running = false;
/**
* Universal Newtonian Time.
*/
public time = 0;
/**
* Creates a new Worls containg a WebGL canvas, a camera, lighting,
* and controllers.
*/
constructor() {
this.engine = new EIGHT.Engine('my-canvas')
.size(500, 500)
.clearColor(0.1, 0.1, 0.1, 1.0)
.enable(EIGHT.Capability.DEPTH_TEST);
this.scene = new EIGHT.Scene(this.engine);
this.camera = new EIGHT.PerspectiveCamera();
this.ambients.push(this.camera)
this.dirLight = new EIGHT.DirectionalLight();
this.ambients.push(this.dirLight)
this.trackball = new EIGHT.TrackballControls(this.camera, window)
// Subscribe to mouse events from the canvas.
this.trackball.subscribe(this.engine.canvas)
this.gui = new dat.GUI({name: 'Yahoo'});
const simFolder = this.gui.addFolder("Simulation")
simFolder.add(this, 'start');
simFolder.add(this, 'stop');
simFolder.add(this, 'reset');
simFolder.open();
const cameraFolder = this.gui.addFolder("Camera")
cameraFolder.add(this, 'planView');
cameraFolder.add(this, 'sideView');
cameraFolder.open();
this.sideView();
}
/**
* This method should be called at the beginning of an animation frame.
* It performs the following tasks:
* 1. Clears the graphics output.
* 2. Updates the camera based upon movements of the mouse.
* 3. Aligns the directional light with the viewing direction.
*/
beginFrame(): void {
this.engine.clear();
// Update the camera based upon mouse events received.
this.trackball.update();
// Keep the directional light pointing in the same direction as the camera.
this.dirLight.direction.copy(this.camera.look).sub(this.camera.eye)
}
/**
* This method should be called after objects have been moved.
*/
draw(): void {
this.scene.draw(this.ambients);
}
/**
* Puts the simulation into the running state.
*/
start(): void {
this.running = true
}
stop(): void {
this.running = false
}
/**
* Resets the universal time property back to zero.
*/
reset(): void {
this.running = false
this.time = 0
}
planView(): void {
this.camera.eye.copy(e3).normalize().scale(29)
this.camera.look.copy(origin)
this.camera.up.copy(e2)
}
sideView(): void {
this.camera.eye.sub2(e3, e2).normalize().scale(33)
this.camera.look.copy(origin)
this.camera.up.copy(e3)
}
/**
* Convenience method for creating a grid in the xy-plane.
*/
createGridXY(options: {
segments?: number;
min?: number;
max?: number;
} = {}): EIGHT.Grid {
const grid = new EIGHT.Grid({
uSegments: options.segments,
uMin: options.min,
uMax: options.max,
vSegments: options.segments,
vMin: options.min,
vMax: options.max
});
this.scene.add(grid);
return grid;
}
/**
* Convenience method for creating a sphere.
*/
createSphere(): EIGHT.Sphere {
const sphere = new EIGHT.Sphere();
this.scene.add(sphere);
return sphere;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment