      1 /*
      2     Copyright 2008-2014
      3         Matthias Ehmann,
      4         Michael Gerhaeuser,
      5         Carsten Miller,
      6         Bianca Valentin,
      7         Alfred Wassermann,
      8         Peter Wilfahrt
      9
     10     This file is part of JSXGraph.
     11
     12     JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
     13
     14     You can redistribute it and/or modify it under the terms of the
     15
     16       * GNU Lesser General Public License as published by
     17         the Free Software Foundation, either version 3 of the License, or
     18         (at your option) any later version
     19       OR
     20       * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
     21
     22     JSXGraph is distributed in the hope that it will be useful,
     23     but WITHOUT ANY WARRANTY; without even the implied warranty of
     24     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     25     GNU Lesser General Public License for more details.
     26
     27     You should have received a copy of the GNU Lesser General Public License and
     28     the MIT License along with JSXGraph. If not, see <http://www.gnu.org/licenses/>
     29     and <http://opensource.org/licenses/MIT/>.
     30  */
     31
     32
     33 /*global JXG: true, define: true*/
     34 /*jslint nomen: true, plusplus: true*/
     35
     36 /* depends:
     37  see define call
     38  */
     39
     40 /**
     41  * @fileoverview Example file for a triangle implemented as a extension to JSXGraph.
     42  */
     43
     44 define([
     45     'jxg', 'options', 'utils/type', 'base/constants', 'base/line', 'base/polygon', 'base/point', 'base/element'
     46 ], function (JXG, Options, Type, Const, Line, Polygon, Point, GeometryElement) {
     47
     48     "use strict";
     49
     50     var priv = {
     51             removeSlopeTriangle: function () {
     52                 Polygon.Polygon.prototype.remove.call(this);
     53
     54                 this.board.removeObject(this.toppoint);
     55                 this.board.removeObject(this.glider);
     56
     57                 this.board.removeObject(this.baseline);
     58                 this.board.removeObject(this.basepoint);
     59
     60                 this.board.removeObject(this.label);
     61             },
     62             Value: function () {
     63                 return this.tangent.getSlope();
     64             }
     65         };
     66
     67     /**
     68      * @class Slope triangle for a point on a line.
     69      * @pseudo
     70      * @name Slopetriangle
     71      * @augments JXG.Line
     72      * @constructor
     73      * @type JXG.Polygon
     74      * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.
     75      * Parameter options:
     76      * @param {JXG.Line} t A tangent based on a glider on some object, e.g. curve, circle, line or turtle.
     77      * @param {JXG.Line_JXG.Point} li, p A line and a point on that line.
     78      *  The user has to take care that the point is a member of the line.
     79      * @example
     80      * // Create a slopetriangle on a tangent
     81      * var f = board.create('plot', ['sin(x)']),
     82      *     g = board.create('glider', [1, 2, f]),
     83      *     t = board.create('tangent', [g]),
     84      *
     85      *     st = board.create('slopetriangle', [t]);
     86      *
     87      * </pre><div id="951ccb6a-52bc-4dc2-80e9-43db064f0f1b" style="width: 300px; height: 300px;"></div>
     88      * <script type="text/javascript">
     89      * (function () {
     90      *   var board = JXG.JSXGraph.initBoard('951ccb6a-52bc-4dc2-80e9-43db064f0f1b', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false}),
     91      *     f = board.create('plot', ['sin(x)']),
     92      *     g = board.create('glider', [1, 2, f]),
     93      *     t = board.create('tangent', [g]),
     94      *
     95      *     st = board.create('slopetriangle', [t]);
     96      * })();
     97      * </script><pre>
     98      *
     99      * @example
    100      * // Create a on a line and a point on that line
    101      * var p1 = board.create('point', [-2, 3]),
    102      *     p2 = board.create('point', [2, -3]),
    103      *     li = board.create('line', [p1, p2]),
    104      *     p = board.create('glider', [0, 0, li]),
    105      *
    106      *     st = board.create('slopetriangle', [li, p]);
    107      *
    108      * </pre><div id="b52f451c-22cf-4677-852a-0bb9d764ee95" style="width: 300px; height: 300px;"></div>
    109      * <script type="text/javascript">
    110      * (function () {
    111      *   var board = JXG.JSXGraph.initBoard('b52f451c-22cf-4677-852a-0bb9d764ee95', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false}),
    112      *     p1 = board.create('point', [-2, 3]),
    113      *     p2 = board.create('point', [2, -3]),
    114      *     li = board.create('line', [p1, p2]),
    115      *     p = board.create('glider', [0, 0, li]),
    116      *
    117      *     st = board.create('slopetriangle', [li, p]);
    118      * })();
    119      * </script><pre>
    120      */
    121     JXG.createSlopeTriangle = function (board, parents, attributes) {
    122         var el, tangent, tglide, glider, toppoint, baseline, basepoint, label, attr;
    123
    124         if (parents.length === 1 && parents[0].type === Const.OBJECT_TYPE_TANGENT) {
    125             tangent = parents[0];
    126             tglide = tangent.glider;
    127         } else if (parents.length === 2 &&
    128                 parents[0].elementClass === Const.OBJECT_CLASS_LINE && Type.isPoint(parents[1])) {
    129             tangent = parents[0];
    130             tglide = parents[1];
    131         } else {
    132             throw new Error("JSXGraph: Can't create slope triangle with parent types '" + (typeof parents[0]) + "'.");
    133         }
    134
    135         attr = Type.copyAttributes(attributes, board.options, 'slopetriangle', 'basepoint');
    136         basepoint = board.create('point', [function () {
    137             return [tglide.X() + 1,  tglide.Y()];
    138         }], attr);
    139
    140         attr = Type.copyAttributes(attributes, board.options, 'slopetriangle', 'baseline');
    141         baseline = board.create('line', [tglide, basepoint], attr);
    142
    143         attr = Type.copyAttributes(attributes, board.options, 'slopetriangle', 'glider');
    144         glider = board.create('glider', [tglide.X() + 1, tglide.Y(), baseline], attr);
    145
    146         attr = Type.copyAttributes(attributes, board.options, 'slopetriangle', 'toppoint');
    147         toppoint = board.create('point', [function () {
    148             return [glider.X(), glider.Y() + (glider.X() - tglide.X()) * tangent.getSlope()];
    149         }], attr);
    150
    151         attr = Type.copyAttributes(attributes, board.options, 'slopetriangle');
    152         el = board.create('polygon', [tglide, glider, toppoint], attr);
    153
    154         el.Value = priv.Value;
    155         el.tangent = tangent;
    156
    157         attr = Type.copyAttributes(attributes, board.options, 'slopetriangle', 'label');
    158         label = board.create('text', [
    159             function () { return glider.X() + 0.1; },
    160             function () { return (glider.Y() + toppoint.Y()) * 0.5; },
    161             function () { return ''; }
    162         ], attr);
    163
    164         label._setText(function () { return el.Value().toFixed(label.visProp.digits); });
    165         label.prepareUpdate().update().updateRenderer();
    166
    167         el.glider = glider;
    168         el.basepoint = basepoint;
    169         el.baseline = baseline;
    170         el.toppoint = toppoint;
    171         el.label = label;
    172
    173         el.methodMap = JXG.deepCopy(el.methodMap, {
    174             tangent: 'tangent',
    175             glider: 'glider',
    176             basepoint: 'basepoint',
    177             baseline: 'baseline',
    178             toppoint: 'toppoint',
    179             label: 'label',
    180             Value: 'Value',
    181             V: 'Value'
    182         });
    183
    184         el.remove = priv.removeSlopeTriangle;
    185
    186         return el;
    187     };
    188
    189     JXG.registerElement('slopetriangle', JXG.createSlopeTriangle);
    190
    191     return {
    192         createSlopeTriangle: JXG.createSlopeTriangle
    193     };
    194 });
    195