|
import { Geometric3 } from 'davinci-eight' |
|
import { Engine, Capability, Scene } from 'davinci-eight' |
|
import { Facet, DirectionalLight, PerspectiveCamera } from 'davinci-eight' |
|
import { TrackballControls } from 'davinci-eight' |
|
import { Color } from 'davinci-eight' |
|
import { Sphere } from 'davinci-eight' |
|
import { Diagram3D } from 'davinci-eight' |
|
import { windowResizer } from './windowResizer' |
|
|
|
const zero = Geometric3.zero(true) |
|
const e1 = Geometric3.e1(true) |
|
const e3 = Geometric3.e3(true) |
|
|
|
import { point, translate, vector } from './h3ga' |
|
import { direction, support } from './h3ga' |
|
// Comment out the following line to use the standard window.requestAnimationFrame |
|
import { requestAnimationFrame } from './requestAnimationFrame' |
|
import { WireCube } from './WireCube' |
|
import { WireLine } from './WireLine' |
|
|
|
const engine = new Engine('canvas3D') |
|
.size(500, 500) |
|
.clearColor(0.0, 0.0, 0.0, 1.0) |
|
.enable(Capability.DEPTH_TEST) |
|
|
|
const scene = new Scene(engine) |
|
|
|
const ambients: Facet[] = [] |
|
|
|
const camera = new PerspectiveCamera() |
|
// |
|
// The following lines move the camera using the Homogeneous Model. |
|
// It's a rather roundabout way of doing something quite simple, but the |
|
// important point is that the translate function distinguishes points from vectors |
|
// and also works for other elements in the model. |
|
// |
|
/** |
|
* The position of the camera in homogeneous coordinates. |
|
*/ |
|
const eye = translate(point(camera.eye), vector(1.5 * e3)) |
|
camera.eye.copyVector(support(eye)) |
|
ambients.push(camera) |
|
|
|
const dirLight = new DirectionalLight() |
|
ambients.push(dirLight) |
|
|
|
const trackball = new TrackballControls(camera, window) |
|
trackball.subscribe(engine.canvas) |
|
// trackball.noPan = true |
|
|
|
/** |
|
* This graphic is just here to create a reference object. |
|
*/ |
|
const wireCube = new WireCube(engine) |
|
scene.add(wireCube) |
|
|
|
/** |
|
* sphere will represent points. |
|
* We don't add it to the scene. |
|
* Instead, we'll render manually in the animation loop. |
|
*/ |
|
const sphere = new Sphere(engine) |
|
sphere.radius = 0.03 |
|
|
|
/** |
|
* wireLine will be used to visualize lines. |
|
* We don't add it to the scene. |
|
* Instead, we'll render manually in the animation loop. |
|
*/ |
|
const wireLine = new WireLine(engine) |
|
wireLine.color = Color.slateblue |
|
|
|
const P = translate(point(+0.5 * e1), vector(zero)) |
|
const Q = translate(point(-0.5 * e1), vector(zero)) |
|
|
|
/** |
|
* A line is the outer product of two points. |
|
*/ |
|
const L = translate(P ^ Q, vector(zero)) |
|
|
|
const overlay = new Diagram3D('canvas2D', camera) |
|
|
|
const animate = function() { |
|
engine.clear() |
|
overlay.clear() |
|
|
|
trackball.update() |
|
|
|
dirLight.direction.copy(camera.look).sub(camera.eye) |
|
|
|
overlay.ctx.fillStyle = "#FFFFFF" |
|
overlay.ctx.font = "20px sans-serif" |
|
|
|
wireLine.a.copyVector(direction(L)) |
|
wireLine.d.copyVector(support(L)) |
|
wireLine.render(ambients) |
|
overlay.fillText('L = P ^ Q', wireLine.d) |
|
|
|
sphere.X.copyVector(support(P)) |
|
sphere.color = Color.red |
|
sphere.render(ambients) |
|
overlay.fillText('P', sphere.X) |
|
|
|
sphere.X.copyVector(support(Q)) |
|
sphere.color = Color.cobalt |
|
sphere.render(ambients) |
|
overlay.fillText('Q', sphere.X) |
|
|
|
scene.render(ambients) |
|
requestAnimationFrame(animate) |
|
} |
|
|
|
windowResizer(engine, camera, overlay).resize() |
|
requestAnimationFrame(animate) |