# Screen3D

#####

declaration
Screen3D

Three dimensional plotting

    var Screen3D = (function (_super) {
    __extends(Screen3D, _super);
    function Screen3D(id, options) {
        if (typeof options === "undefined") { options = {}; }
        _super.call(this, id, options);
        this.type = 'screen3D';

        var defaults = {
            anaglyphMode: false,
            axes: true,
            background: 0xffffff,
            camera: {
                lookAt: [0, 0, 0],
                position: [10, 10, 10]
            },
            controls: 'Trackball',
            grid: {
                xy: {
                    angle: Math.PI / 8,
                    color: 0xcccccc,
                    type: 'none',
                    tick: { x: 1, y: 1, r: 1 }
                },
                xz: {
                    angle: Math.PI / 8,
                    color: 0xcccccc,
                    type: 'none',
                    tick: { x: 1, z: 1, r: 1 }
                },
                yz: {
                    angle: Math.PI / 8,
                    color: 0xcccccc,
                    type: 'none',
                    tick: { y: 1, z: 1, r: 1 }
                }
            },
            height: 500,
            renderer: 'WebGL',
            width: 500
        }, opts = MathLib.extendObject(defaults, options), scene = new THREE.Scene(), camera, renderer, controls, viewAngle, aspect, near, far;

        this.options = opts;
        this.scene = scene;

        // Camera
        // ======
        viewAngle = 45;
        aspect = opts.width / opts.height;
        near = 0.1;
        far = 20000;

        camera = new THREE.PerspectiveCamera(viewAngle, aspect, near, far);
        camera.position = to3js(opts.camera.position);
        camera.lookAt(to3js(opts.camera.lookAt));
        camera.up = new THREE.Vector3(0, 0, 1);
        scene.add(camera);

        // Renderer
        // ========
        renderer = new THREE[opts.renderer + 'Renderer']({ antialias: true, preserveDrawingBuffer: true });

        // Remove the warning message.
        this.wrapper.innerHTML = '';
        this.wrapper.appendChild(renderer.domElement);

        // Storing the the original renderer to recover it easily when leaving anaglyph mode
        var origRenderer = renderer;

        // Overwrite the renderer with the anaglyph mode renderer
        if (opts.anaglyphMode) {
            renderer = new THREE.AnaglyphEffect(renderer);
        }

        renderer.setSize(opts.width, opts.height);

        // Controls
        // ========
        // Other possible values are: 'FirstPerson', 'Fly', 'Orbit', 'Path', 'Roll', 'Trackback' or false
        // MathLib defaults to the TrackballControls
        // move mouse and left   click (or hold 'A') to rotate
        //                middle click (or hold 'S') to zoom
        //                right  click (or hold 'D') to pan
        if (opts.controls) {
            controls = new THREE[opts.controls + 'Controls'](camera, renderer.domElement);
        } else {
            controls = {
                update: function () {
                }
            };
        }

        // Light
        // =====
        var light1 = new THREE.PointLight(0xffffff);
        light1.position.set(0, 0, 200);
        scene.add(light1);
        var light2 = new THREE.PointLight(0xffffff);
        light2.position.set(0, 0, -200);
        scene.add(light2);

        // Background
        // ==========
        renderer.setClearColorHex(opts.background, 1);
        renderer.clear();

        // Grid
        // ====
        if (opts.grid) {
            this.drawGrid();
        }

        // Axes
        // ====
        if (opts.axes) {
            var axes = new THREE.AxisHelper(10);
            scene.add(axes);
        }

        // Animate the scene
        // =================
        function animate () {
            requestAnimationFrame(animate);
            render();
            update();
        }

        function update () {
            //var delta = clock.getDelta();
            controls.update();
        }

        // Render the scene
        function render () {
            renderer.render(scene, camera);
        }

        // kick of the animation loop
        animate();

        this.options = opts;
        this.element = renderer.domElement;
        this.renderer = renderer;
        this.camera = camera;

        this.container.classList.add('MathLib_screen3D');
    }

# drawGrid

#####

method
Screen3D.prototype.drawGrid() → Screen3D

Draws the grid.

    Screen3D.prototype.drawGrid = function () {
        if (!this.options.grid) {
            return this;
        }

        var _this = this, gridDrawer = function (opts, rotX, rotY) {
            var size = 10, grid = new THREE.Object3D(), color = new THREE.Color(opts.color), i, ii;

            if (opts.type === 'cartesian') {
                var tickX = 'x' in opts.tick ? opts.tick.x : opts.tick.y, tickY = 'z' in opts.tick ? opts.tick.z : opts.tick.y, lines = new THREE.Shape();

                for (i = -size; i <= size; i += tickX) {
                    lines.moveTo(-size, i);
                    lines.lineTo(size, i);
                }

                for (i = -size; i <= size; i += tickY) {
                    lines.moveTo(i, -size);
                    lines.lineTo(i, size);
                }

                grid.add(new THREE.Line(lines.createPointsGeometry(), new THREE.LineBasicMaterial({ color: color }), THREE.LinePieces));

                grid.rotation.x = rotX;
                grid.rotation.y = rotY;

                _this.scene.add(grid);
            } else if (opts.type === 'polar') {
                var circles = new THREE.Shape(), rays = new THREE.Shape();

                for (i = 0; i <= size; i += opts.tick.r) {
                    circles.moveTo(i, 0);
                    circles.absarc(0, 0, i, 0, 2 * Math.PI + 0.001, false);
                }
                grid.add(new THREE.Line(circles.createPointsGeometry(), new THREE.LineBasicMaterial({ color: color })));

                for (i = 0, ii = 2 * Math.PI; i < ii; i += opts.angle) {
                    rays.moveTo(0, 0);
                    rays.lineTo(size * Math.cos(i), size * Math.sin(i));
                }

                grid.add(new THREE.Line(rays.createPointsGeometry(), new THREE.LineBasicMaterial({ color: color })));

                grid.rotation.x = rotX;
                grid.rotation.y = rotY;

                _this.scene.add(grid);
            }
        };

        gridDrawer(this.options.grid.xy, 0, 0);
        gridDrawer(this.options.grid.xz, Math.PI / 2, 0);
        gridDrawer(this.options.grid.yz, 0, Math.PI / 2);

        return this;
    };

# parametricPlot3D

#####

method
Screen3D.prototype.parametricPlot3D() → Screen3D

Option name | Type | Description
--- | --- | ---
f | function | The function which is called on every argument
options | object | Optional drawing options

Creates a parametric plot

    Screen3D.prototype.parametricPlot3D = function (f, options) {
        var defaults = {
            closed: false,
            debug: false,
            min: 0,
            max: 1,
            pointNum: 1000,
            radius: 0.05,
            segmentsRadius: 6,
            material: {
                type: 'MeshLambert'
            }
        }, opts = MathLib.extendObject(defaults, options), Curve = THREE.Curve.create(function () {
        }, function (t) {
            t = (opts.max - opts.min) * t + opts.min;
            var ft = f(t);
            return new THREE.Vector3(ft[0], ft[1], ft[2]);
        }), mesh = new THREE.Mesh(new THREE.TubeGeometry(new Curve(), opts.pointNum, opts.radius, opts.segmentsRadius, opts.closed, opts.debug), new THREE[opts.material.type + 'Material'](opts.material));

        this.scene.add(mesh);

guiObj = {
color: [mesh.material.color.r, mesh.material.color.g, mesh.material.color.b]
};

            var folder = _3D.datGUI.addFolder(options.name);
            folder.add(mesh, 'visible');
            folder.addColor(guiObj, 'color')
            .onChange(function (value) {mesh.material.color.setRGB(value[0] / 255, value[1] / 255, value[2] / 255);});

    return this;
    };

# plot3D

#####

method
Screen3D.prototype.plot3D() → Screen3D

Option name | Type | Description
--- | --- | ---
f | function | The map for the height
options | object | Optional drawing options

Creates a plot of a three dimensional function

    Screen3D.prototype.plot3D = function (f, options) {
        return this.surfacePlot3D(function (u, v) {
            return [u, v, f(u, v)];
        }, options);
    };

# resize

#####

method
Screen3D.prototype.resize() → Screen3D

Option name | Type | Description
--- | --- | ---
width | number | The new width
height | number | The new height

Adjust the rendering if the screen is resized

    Screen3D.prototype.resize = function (width, height) {
        this.renderer.setSize(width, height);
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();

        return this;
    };

# surfacePlot3D

#####

method
Screen3D.prototype.surfacePlot3D() → Screen3D

Option name | Type | Description
--- | --- | ---
f | function | The map for the surface
options | object | Optional drawing options

Creates a surface plot.

    Screen3D.prototype.surfacePlot3D = function (f, options) {
        var defaults = {
            material: {
                type: 'MeshLambert'
            },
            pointNumX: 100,
            pointNumY: 100,
            xmin: 0,
            xmax: 1,
            ymin: 0,
            ymax: 1
        }, opts = MathLib.extendObject(defaults, options), map = function (u, v) {
            u = (opts.xmax - opts.xmin) * u + opts.xmin;
            v = (opts.ymax - opts.ymin) * v + opts.ymin;
            var fuv = f(u, v);
            return new THREE.Vector3(fuv[0], fuv[1], fuv[2]);
        }, material = new THREE[opts.material.type + 'Material'](opts.material), mesh;

        material.side = THREE.DoubleSide;

        mesh = new THREE.Mesh(new THREE.ParametricGeometry(map, opts.pointNumX, opts.pointNumY, false), material);

        this.scene.add(mesh);

        // if (options.datGUI) {
        //   guiObj = {
        //     color: [mesh.material.color.r, mesh.material.color.g, mesh.material.color.b]
        //   };
        //   var folder = _3D.datGUI.addFolder(options.datGUI.name);
        //   if (options.datGUI.visible) {
        //     folder.add(mesh, 'visible');
        //   }
        //   if (options.datGUI.wireframe) {
        //     folder.add(mesh.material, 'wireframe');
        //   }
        //   if (options.datGUI.color) {
        //     color = mesh.material.color.getHex();
        //     var guiObj = {
        //       color: color
        //     };
        //     folder.addColor(guiObj, 'color').name('color')
        //       .onChange(function (value) {mesh.material.color = new THREE.Color(value);});
        //   }
        // }
        return this;
    };
    return Screen3D;
        })(MathLib.Screen);
        MathLib.Screen3D = Screen3D;
    })(MathLib || (MathLib = {}));