1 /* 2 Copyright 2008-2023 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 <https://www.gnu.org/licenses/> 29 and <https://opensource.org/licenses/MIT/>. 30 */ 31 32 /*global JXG: true, define: true*/ 33 /*jslint nomen: true, plusplus: true*/ 34 35 /** 36 * @fileoverview Example file for a triangle implemented as a extension to JSXGraph. 37 */ 38 39 import JXG from "../jxg"; 40 import Type from "../utils/type"; 41 import Const from "../base/constants"; 42 import Polygon from "../base/polygon"; 43 44 var priv = { 45 removeSlopeTriangle: function () { 46 Polygon.prototype.remove.call(this); 47 48 this.board.removeObject(this.toppoint); 49 this.board.removeObject(this.glider); 50 51 this.board.removeObject(this.baseline); 52 this.board.removeObject(this.basepoint); 53 54 this.board.removeObject(this.label); 55 56 if (this._isPrivateTangent) { 57 this.board.removeObject(this.tangent); 58 } 59 }, 60 Value: function () { 61 return this.tangent.getSlope(); 62 } 63 }; 64 65 /** 66 * @class Slope triangle for a point on a line. 67 * @pseudo 68 * @name Slopetriangle 69 * @augments JXG.Line 70 * @constructor 71 * @type JXG.Polygon 72 * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown. 73 * Parameter options: 74 * @param {JXG.Line} t A tangent based on a glider on some object, e.g. curve, circle, line or turtle. 75 * @param {JXG.Line_JXG.Point} li, p A line and a point on that line. 76 * The user has to take care that the point is a member of the line. 77 * @example 78 * // Create a slopetriangle on a tangent 79 * var f = board.create('plot', ['sin(x)']), 80 * g = board.create('glider', [1, 2, f]), 81 * t = board.create('tangent', [g]), 82 * 83 * st = board.create('slopetriangle', [t]); 84 * 85 * </pre><div class="jxgbox" id="JXG951ccb6a-52bc-4dc2-80e9-43db064f0f1b" style="width: 300px; height: 300px;"></div> 86 * <script type="text/javascript"> 87 * (function () { 88 * var board = JXG.JSXGraph.initBoard('JXG951ccb6a-52bc-4dc2-80e9-43db064f0f1b', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false}), 89 * f = board.create('plot', ['sin(x)']), 90 * g = board.create('glider', [1, 2, f]), 91 * t = board.create('tangent', [g]), 92 * 93 * st = board.create('slopetriangle', [t]); 94 * })(); 95 * </script><pre> 96 * 97 * @example 98 * // Create a on a line and a point on that line 99 * var p1 = board.create('point', [-2, 3]), 100 * p2 = board.create('point', [2, -3]), 101 * li = board.create('line', [p1, p2]), 102 * p = board.create('glider', [0, 0, li]), 103 * 104 * st = board.create('slopetriangle', [li, p]); 105 * 106 * </pre><div class="jxgbox" id="JXGb52f451c-22cf-4677-852a-0bb9d764ee95" style="width: 300px; height: 300px;"></div> 107 * <script type="text/javascript"> 108 * (function () { 109 * var board = JXG.JSXGraph.initBoard('JXGb52f451c-22cf-4677-852a-0bb9d764ee95', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false}), 110 * p1 = board.create('point', [-2, 3]), 111 * p2 = board.create('point', [2, -3]), 112 * li = board.create('line', [p1, p2]), 113 * p = board.create('glider', [0, 0, li]), 114 * 115 * st = board.create('slopetriangle', [li, p]); 116 * })(); 117 * </script><pre> 118 */ 119 JXG.createSlopeTriangle = function (board, parents, attributes) { 120 var el, tangent, tglide, glider, 121 toppoint, baseline, basepoint, 122 label, attr, 123 isPrivateTangent = false; 124 125 if (parents.length === 1 && parents[0].type === Const.OBJECT_TYPE_TANGENT) { 126 tangent = parents[0]; 127 tglide = tangent.glider; 128 } else if (parents.length === 1 && parents[0].type === Const.OBJECT_TYPE_GLIDER) { 129 tglide = parents[0]; 130 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "tangent"); 131 tangent = board.create("tangent", [tglide], attr); 132 isPrivateTangent = true; 133 } else if ( 134 parents.length === 2 && 135 parents[0].elementClass === Const.OBJECT_CLASS_LINE && 136 Type.isPoint(parents[1]) 137 ) { 138 tangent = parents[0]; 139 tglide = parents[1]; 140 } else { 141 throw new Error( 142 "JSXGraph: Can't create slope triangle with parent types '" + 143 typeof parents[0] + 144 "'." 145 ); 146 } 147 148 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "basepoint"); 149 basepoint = board.create( 150 "point", 151 [ 152 function () { 153 return [tglide.X() + 1, tglide.Y()]; 154 } 155 ], 156 attr 157 ); 158 159 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "baseline"); 160 baseline = board.create("line", [tglide, basepoint], attr); 161 162 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "glider"); 163 glider = board.create("glider", [tglide.X() + 1, tglide.Y(), baseline], attr); 164 165 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "toppoint"); 166 toppoint = board.create( 167 "point", 168 [ 169 function () { 170 return [ 171 glider.X(), 172 glider.Y() + (glider.X() - tglide.X()) * tangent.getSlope() 173 ]; 174 } 175 ], 176 attr 177 ); 178 179 attr = Type.copyAttributes(attributes, board.options, "slopetriangle"); 180 attr.borders = Type.copyAttributes(attr.borders, board.options, "slopetriangle", "borders"); 181 el = board.create("polygon", [tglide, glider, toppoint], attr); 182 183 /** 184 * Returns the value of the slope triangle, that is the slope of the tangent. 185 * @name Value 186 * @memberOf Slopetriangle.prototype 187 * @function 188 * @returns {Number} slope of the tangent. 189 */ 190 el.Value = priv.Value; 191 el.tangent = tangent; 192 el._isPrivateTangent = isPrivateTangent; 193 194 //el.borders[0].setArrow(false, {type: 2, size: 10}); 195 //el.borders[1].setArrow(false, {type: 2, size: 10}); 196 el.borders[2].setArrow(false, false); 197 198 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "label"); 199 label = board.create( 200 "text", 201 [ 202 function () { 203 return glider.X() + 0.1; 204 }, 205 function () { 206 return (glider.Y() + toppoint.Y()) * 0.5; 207 }, 208 function () { 209 return ""; 210 } 211 ], 212 attr 213 ); 214 215 label._setText(function () { 216 var digits = Type.evaluate(label.visProp.digits); 217 218 if (label.useLocale()) { 219 return label.formatNumberLocale(el.Value(), digits); 220 } 221 return Type.toFixed(el.Value(), digits); 222 }); 223 label.fullUpdate(); 224 225 el.glider = glider; 226 el.basepoint = basepoint; 227 el.baseline = baseline; 228 el.toppoint = toppoint; 229 el.label = label; 230 231 el.subs = { 232 glider: glider, 233 basePoint: basepoint, 234 baseLine: baseline, 235 topPoint: toppoint, 236 label: label 237 }; 238 el.inherits.push(glider, basepoint, baseline, toppoint, label); 239 240 el.methodMap = JXG.deepCopy(el.methodMap, { 241 tangent: "tangent", 242 glider: "glider", 243 basepoint: "basepoint", 244 baseline: "baseline", 245 toppoint: "toppoint", 246 label: "label", 247 Value: "Value", 248 V: "Value" 249 }); 250 251 el.remove = priv.removeSlopeTriangle; 252 253 return el; 254 }; 255 256 JXG.registerElement("slopetriangle", JXG.createSlopeTriangle); 257 258 // export default { 259 // createSlopeTriangle: JXG.createSlopeTriangle 260 // }; 261