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, 121 tangent, 122 tglide, 123 glider, 124 toppoint, 125 baseline, 126 basepoint, 127 label, 128 attr, 129 isPrivateTangent = false; 130 131 if (parents.length === 1 && parents[0].type === Const.OBJECT_TYPE_TANGENT) { 132 tangent = parents[0]; 133 tglide = tangent.glider; 134 } else if (parents.length === 1 && parents[0].type === Const.OBJECT_TYPE_GLIDER) { 135 tglide = parents[0]; 136 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "tangent"); 137 tangent = board.create("tangent", [tglide], attr); 138 isPrivateTangent = true; 139 } else if ( 140 parents.length === 2 && 141 parents[0].elementClass === Const.OBJECT_CLASS_LINE && 142 Type.isPoint(parents[1]) 143 ) { 144 tangent = parents[0]; 145 tglide = parents[1]; 146 } else { 147 throw new Error( 148 "JSXGraph: Can't create slope triangle with parent types '" + 149 typeof parents[0] + 150 "'." 151 ); 152 } 153 154 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "basepoint"); 155 basepoint = board.create( 156 "point", 157 [ 158 function () { 159 return [tglide.X() + 1, tglide.Y()]; 160 } 161 ], 162 attr 163 ); 164 165 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "baseline"); 166 baseline = board.create("line", [tglide, basepoint], attr); 167 168 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "glider"); 169 glider = board.create("glider", [tglide.X() + 1, tglide.Y(), baseline], attr); 170 171 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "toppoint"); 172 toppoint = board.create( 173 "point", 174 [ 175 function () { 176 return [ 177 glider.X(), 178 glider.Y() + (glider.X() - tglide.X()) * tangent.getSlope() 179 ]; 180 } 181 ], 182 attr 183 ); 184 185 attr = Type.copyAttributes(attributes, board.options, "slopetriangle"); 186 attr.borders = Type.copyAttributes(attr.borders, board.options, "slopetriangle", "borders"); 187 el = board.create("polygon", [tglide, glider, toppoint], attr); 188 189 /** 190 * Returns the value of the slope triangle, that is the slope of the tangent. 191 * @name Value 192 * @memberOf Slopetriangle.prototype 193 * @function 194 * @returns {Number} slope of the tangent. 195 */ 196 el.Value = priv.Value; 197 el.tangent = tangent; 198 el._isPrivateTangent = isPrivateTangent; 199 200 //el.borders[0].setArrow(false, {type: 2, size: 10}); 201 //el.borders[1].setArrow(false, {type: 2, size: 10}); 202 el.borders[2].setArrow(false, false); 203 204 attr = Type.copyAttributes(attributes, board.options, "slopetriangle", "label"); 205 label = board.create( 206 "text", 207 [ 208 function () { 209 return glider.X() + 0.1; 210 }, 211 function () { 212 return (glider.Y() + toppoint.Y()) * 0.5; 213 }, 214 function () { 215 return ""; 216 } 217 ], 218 attr 219 ); 220 221 label._setText(function () { 222 return Type.toFixed(el.Value(), Type.evaluate(label.visProp.digits)); 223 }); 224 label.fullUpdate(); 225 226 el.glider = glider; 227 el.basepoint = basepoint; 228 el.baseline = baseline; 229 el.toppoint = toppoint; 230 el.label = label; 231 232 el.subs = { 233 glider: glider, 234 basePoint: basepoint, 235 baseLine: baseline, 236 topPoint: toppoint, 237 label: label 238 }; 239 el.inherits.push(glider, basepoint, baseline, toppoint, label); 240 241 el.methodMap = JXG.deepCopy(el.methodMap, { 242 tangent: "tangent", 243 glider: "glider", 244 basepoint: "basepoint", 245 baseline: "baseline", 246 toppoint: "toppoint", 247 label: "label", 248 Value: "Value", 249 V: "Value" 250 }); 251 252 el.remove = priv.removeSlopeTriangle; 253 254 return el; 255 }; 256 257 JXG.registerElement("slopetriangle", JXG.createSlopeTriangle); 258 259 // export default { 260 // createSlopeTriangle: JXG.createSlopeTriangle 261 // }; 262