1 /* 2 Copyright 2008-2024 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 In this file the geometry object Arc is defined. Arc stores all 37 * style and functional properties that are required to draw an arc on a board. 38 */ 39 40 import JXG from "../jxg.js"; 41 import Geometry from "../math/geometry.js"; 42 import Mat from "../math/math.js"; 43 import Coords from "../base/coords.js"; 44 import Circle from "../base/circle.js"; 45 import Type from "../utils/type.js"; 46 import Const from "../base/constants.js"; 47 48 /** 49 * @class An arc is a partial circumference line of a circle. 50 * It is defined by a center, one point that 51 * defines the radius, and a third point that defines the angle of the arc. 52 * 53 * @pseudo 54 * @name Arc 55 * @augments Curve 56 * @constructor 57 * @type JXG.Curve 58 * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown. 59 * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be an arc of a circle around p1 through p2. The arc is drawn 60 * counter-clockwise from p2 to p3. 61 * @example 62 * // Create an arc out of three free points 63 * var p1 = board.create('point', [2.0, 2.0]); 64 * var p2 = board.create('point', [1.0, 0.5]); 65 * var p3 = board.create('point', [3.5, 1.0]); 66 * 67 * var a = board.create('arc', [p1, p2, p3]); 68 * board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}]) 69 * </pre><div class="jxgbox" id="JXG114ef584-4a5e-4686-8392-c97501befb5b" style="width: 300px; height: 300px;"></div> 70 * <script type="text/javascript"> 71 * (function () { 72 * var board = JXG.JSXGraph.initBoard('JXG114ef584-4a5e-4686-8392-c97501befb5b', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}), 73 * p1 = board.create('point', [2.0, 2.0]), 74 * p2 = board.create('point', [1.0, 0.5]), 75 * p3 = board.create('point', [3.5, 1.0]), 76 * 77 * a = board.create('arc', [p1, p2, p3]); 78 * board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}]) 79 * })(); 80 * </script><pre> 81 * 82 * @example 83 * var t = board.create('transform', [2, 1.5], {type: 'scale'}); 84 * var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'}); 85 * var a2 = board.create('curve', [a1, t], {strokeColor: 'red'}); 86 * 87 * </pre><div id="JXG1949da46-6339-11e8-9fb9-901b0e1b8723" class="jxgbox" style="width: 300px; height: 300px;"></div> 88 * <script type="text/javascript"> 89 * (function() { 90 * var board = JXG.JSXGraph.initBoard('JXG1949da46-6339-11e8-9fb9-901b0e1b8723', 91 * {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false}); 92 * var t = board.create('transform', [2, 1.5], {type: 'scale'}); 93 * var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'}); 94 * var a2 = board.create('curve', [a1, t], {strokeColor: 'red'}); 95 * 96 * })(); 97 * 98 * </script><pre> 99 * 100 */ 101 JXG.createArc = function (board, parents, attributes) { 102 var el, attr, points; 103 104 // attributes.radiusPoint = {visible: false}; 105 points = Type.providePoints(board, parents, attributes, "arc", [ 106 "center", 107 "radiuspoint", 108 "anglepoint" 109 ]); 110 if (points === false || points.length < 3) { 111 throw new Error( 112 "JSXGraph: Can't create Arc with parent types '" + 113 typeof parents[0] + 114 "' and '" + 115 typeof parents[1] + 116 "' and '" + 117 typeof parents[2] + 118 "'." + 119 "\nPossible parent types: [point,point,point], [arc, transformation]" 120 ); 121 } 122 123 attr = Type.copyAttributes(attributes, board.options, "arc"); 124 el = board.create("curve", [[0], [0]], attr); 125 126 el.elType = "arc"; 127 el.setParents(points); 128 129 /** 130 * documented in JXG.GeometryElement 131 * @ignore 132 */ 133 el.type = Const.OBJECT_TYPE_ARC; 134 135 /** 136 * Center of the arc. 137 * @memberOf Arc.prototype 138 * @name center 139 * @type JXG.Point 140 */ 141 el.center = points[0]; 142 143 /** 144 * Point defining the arc's radius. 145 * @memberOf Arc.prototype 146 * @name radiuspoint 147 * @type JXG.Point 148 */ 149 el.radiuspoint = points[1]; 150 el.point2 = el.radiuspoint; 151 152 /** 153 * The point defining the arc's angle. 154 * @memberOf Arc.prototype 155 * @name anglepoint 156 * @type JXG.Point 157 */ 158 el.anglepoint = points[2]; 159 el.point3 = el.anglepoint; 160 161 // Add arc as child to defining points 162 // or vice versa if the points are provided as coordinates 163 if (Type.exists(el.center._is_new)) { 164 el.addChild(el.center); 165 delete el.center._is_new; 166 } else { 167 el.center.addChild(el); 168 } 169 if (Type.exists(el.radiuspoint._is_new)) { 170 el.addChild(el.radiuspoint); 171 delete el.radiuspoint._is_new; 172 } else { 173 el.radiuspoint.addChild(el); 174 } 175 if (Type.exists(el.anglepoint._is_new)) { 176 el.addChild(el.anglepoint); 177 delete el.anglepoint._is_new; 178 } else { 179 el.anglepoint.addChild(el); 180 } 181 182 // This attribute is necessary for circumCircleArcs 183 el.useDirection = attr.usedirection; // This makes the attribute immutable 184 185 // documented in JXG.Curve 186 /** 187 * @class 188 * @ignore 189 */ 190 el.updateDataArray = function () { 191 var ar, phi, det, 192 p0c, p1c, p2c, 193 sgn = 1, 194 A = this.radiuspoint, 195 B = this.center, 196 C = this.anglepoint, 197 ev_s = this.evalVisProp('selection'); 198 199 phi = Geometry.rad(A, B, C); 200 if ((ev_s === "minor" && phi > Math.PI) || (ev_s === "major" && phi < Math.PI)) { 201 sgn = -1; 202 } 203 204 // This is true for circumCircleArcs. In that case there is 205 // a fourth parent element: [center, point1, point3, point2] 206 if (this.useDirection) { 207 p0c = points[1].coords.usrCoords; 208 p1c = points[3].coords.usrCoords; 209 p2c = points[2].coords.usrCoords; 210 det = (p0c[1] - p2c[1]) * (p0c[2] - p1c[2]) - (p0c[2] - p2c[2]) * (p0c[1] - p1c[1]); 211 212 if (det < 0) { 213 this.radiuspoint = points[1]; 214 this.anglepoint = points[2]; 215 } else { 216 this.radiuspoint = points[2]; 217 this.anglepoint = points[1]; 218 } 219 } 220 221 A = A.coords.usrCoords; 222 B = B.coords.usrCoords; 223 C = C.coords.usrCoords; 224 225 ar = Geometry.bezierArc(A, B, C, false, sgn); 226 227 this.dataX = ar[0]; 228 this.dataY = ar[1]; 229 230 this.bezierDegree = 3; 231 232 this.updateStdform(); 233 this.updateQuadraticform(); 234 }; 235 236 /** 237 * Determines the arc's current radius. I.e. the distance between {@link Arc#center} and {@link Arc#radiuspoint}. 238 * @memberOf Arc.prototype 239 * @name Radius 240 * @function 241 * @returns {Number} The arc's radius 242 */ 243 el.Radius = function () { 244 return this.radiuspoint.Dist(this.center); 245 }; 246 247 /** 248 * @deprecated Use {@link Arc#Radius} 249 * @memberOf Arc.prototype 250 * @name getRadius 251 * @function 252 * @returns {Number} 253 */ 254 el.getRadius = function () { 255 JXG.deprecated("Arc.getRadius()", "Arc.Radius()"); 256 return this.Radius(); 257 }; 258 259 /** 260 * Returns the length of the arc or the value of the angle spanned by the arc. 261 * @memberOf Arc.prototype 262 * @name Value 263 * @function 264 * @param {String} [unit='length'] Unit of the returned values. Possible units are 265 * <ul> 266 * <li> 'length' (default): length of the arc line 267 * <li> 'radians': angle spanned by the arc in radians 268 * <li> 'degrees': angle spanned by the arc in degrees 269 * <li> 'semicircle': angle spanned by the arc in radians as a multiple of π, e.g. if the angle is 1.5π, 1.5 will be returned. 270 * <li> 'circle': angle spanned by the arc in radians as a multiple of 2π 271 * </ul> 272 * It is sufficient to supply the first three characters of the unit, e.g. 'len'. 273 * @param {Number} [rad=undefined] Value of angle which can be used instead of the generic one. 274 * @returns {Number} The arc length or the angle value in various units. 275 */ 276 el.Value = function (unit, rad) { 277 var val; 278 279 rad = rad || Geometry.rad(this.radiuspoint, this.center, this.anglepoint); 280 281 unit = unit || 'length'; 282 unit = unit.toLocaleLowerCase(); 283 if (unit === '' || unit.indexOf('len') === 0) { 284 val = rad * this.Radius(); 285 } else if (unit.indexOf('rad') === 0) { 286 val = rad; 287 } else if (unit.indexOf('deg') === 0) { 288 val = rad * 180 / Math.PI; 289 } else if (unit.indexOf('sem') === 0) { 290 val = rad / Math.PI; 291 } else if (unit.indexOf('cir') === 0) { 292 val = rad * 0.5 / Math.PI; 293 } 294 295 return val; 296 }; 297 298 /** 299 * Arc length. 300 * @memberOf Arc.prototype 301 * @name L 302 * @returns {Number} Length of the arc. 303 * @see Arc#Value 304 */ 305 el.L = function() { 306 return this.Value('length'); 307 }; 308 309 // documented in geometry element 310 el.hasPoint = function (x, y) { 311 var dist, 312 checkPoint, 313 has, 314 invMat, 315 c, 316 prec, 317 type, 318 r = this.Radius(); 319 320 if (this.evalVisProp('hasinnerpoints')) { 321 return this.hasPointSector(x, y); 322 } 323 324 if (Type.isObject(this.evalVisProp('precision'))) { 325 type = this.board._inputDevice; 326 prec = this.evalVisProp('precision.' + type); 327 } else { 328 // 'inherit' 329 prec = this.board.options.precision.hasPoint; 330 } 331 prec /= Math.min(Math.abs(this.board.unitX), Math.abs(this.board.unitY)); 332 checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board); 333 334 if (this.transformations.length > 0) { 335 // Transform the mouse/touch coordinates 336 // back to the original position of the curve. 337 this.updateTransformMatrix(); 338 invMat = Mat.inverse(this.transformMat); 339 c = Mat.matVecMult(invMat, checkPoint.usrCoords); 340 checkPoint = new Coords(Const.COORDS_BY_USER, c, this.board); 341 } 342 343 dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint); 344 has = Math.abs(dist - r) < prec; 345 346 /** 347 * At that point we know that the user has touched the circle line. 348 * Now, we have to check, if the user has hit the arc path. 349 */ 350 if (has) { 351 has = Geometry.coordsOnArc(this, checkPoint); 352 } 353 return has; 354 }; 355 356 /** 357 * Checks whether (x,y) is within the sector defined by the arc. 358 * @memberOf Arc.prototype 359 * @name hasPointSector 360 * @function 361 * @param {Number} x Coordinate in x direction, screen coordinates. 362 * @param {Number} y Coordinate in y direction, screen coordinates. 363 * @returns {Boolean} True if (x,y) is within the sector defined by the arc, False otherwise. 364 */ 365 el.hasPointSector = function (x, y) { 366 var checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board), 367 r = this.Radius(), 368 dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint), 369 has = dist < r; 370 371 if (has) { 372 has = Geometry.coordsOnArc(this, checkPoint); 373 } 374 return has; 375 }; 376 377 // documented in geometry element 378 el.getTextAnchor = function () { 379 return this.center.coords; 380 }; 381 382 // documented in geometry element 383 /** 384 * @class 385 * @ignore 386 */ 387 el.getLabelAnchor = function () { 388 var coords, 389 vec, 390 vecx, 391 vecy, 392 len, 393 angle = Geometry.rad(this.radiuspoint, this.center, this.anglepoint), 394 dx = 10 / this.board.unitX, 395 dy = 10 / this.board.unitY, 396 p2c = this.point2.coords.usrCoords, 397 pmc = this.center.coords.usrCoords, 398 bxminusax = p2c[1] - pmc[1], 399 byminusay = p2c[2] - pmc[2], 400 ev_s = this.evalVisProp('selection'), 401 l_vp = this.label ? this.label.visProp : this.visProp.label; 402 403 // If this is uncommented, the angle label can not be dragged 404 //if (Type.exists(this.label)) { 405 // this.label.relativeCoords = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this.board); 406 //} 407 408 if ((ev_s === "minor" && angle > Math.PI) || (ev_s === "major" && angle < Math.PI)) { 409 angle = -(2 * Math.PI - angle); 410 } 411 412 coords = new Coords( 413 Const.COORDS_BY_USER, 414 [ 415 pmc[1] + Math.cos(angle * 0.5) * bxminusax - Math.sin(angle * 0.5) * byminusay, 416 pmc[2] + Math.sin(angle * 0.5) * bxminusax + Math.cos(angle * 0.5) * byminusay 417 ], 418 this.board 419 ); 420 421 vecx = coords.usrCoords[1] - pmc[1]; 422 vecy = coords.usrCoords[2] - pmc[2]; 423 424 len = Mat.hypot(vecx, vecy); 425 vecx = (vecx * (len + dx)) / len; 426 vecy = (vecy * (len + dy)) / len; 427 vec = [pmc[1] + vecx, pmc[2] + vecy]; 428 429 l_vp.position = Geometry.calcLabelQuadrant(Geometry.rad([1, 0], [0, 0], vec)); 430 431 return new Coords(Const.COORDS_BY_USER, vec, this.board); 432 }; 433 434 // documentation in jxg.circle 435 el.updateQuadraticform = Circle.prototype.updateQuadraticform; 436 437 // documentation in jxg.circle 438 el.updateStdform = Circle.prototype.updateStdform; 439 440 el.methodMap = JXG.deepCopy(el.methodMap, { 441 getRadius: "getRadius", 442 radius: "Radius", 443 Radius: "Radius", 444 center: "center", 445 radiuspoint: "radiuspoint", 446 anglepoint: "anglepoint", 447 Value: "Value", 448 L: "L" 449 }); 450 451 el.prepareUpdate().update(); 452 return el; 453 }; 454 455 JXG.registerElement("arc", JXG.createArc); 456 457 /** 458 * @class A semicircle is a special arc defined by two points. The arc hits both points. 459 * @pseudo 460 * @name Semicircle 461 * @augments Arc 462 * @constructor 463 * @type Arc 464 * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown. 465 * @param {JXG.Point_JXG.Point} p1,p2 The result will be a composition of an arc drawn clockwise from <tt>p1</tt> and 466 * <tt>p2</tt> and the midpoint of <tt>p1</tt> and <tt>p2</tt>. 467 * @example 468 * // Create an arc out of three free points 469 * var p1 = board.create('point', [4.5, 2.0]); 470 * var p2 = board.create('point', [1.0, 0.5]); 471 * 472 * var a = board.create('semicircle', [p1, p2]); 473 * </pre><div class="jxgbox" id="JXG5385d349-75d7-4078-b732-9ae808db1b0e" style="width: 300px; height: 300px;"></div> 474 * <script type="text/javascript"> 475 * (function () { 476 * var board = JXG.JSXGraph.initBoard('JXG5385d349-75d7-4078-b732-9ae808db1b0e', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}), 477 * p1 = board.create('point', [4.5, 2.0]), 478 * p2 = board.create('point', [1.0, 0.5]), 479 * 480 * sc = board.create('semicircle', [p1, p2]); 481 * })(); 482 * </script><pre> 483 */ 484 JXG.createSemicircle = function (board, parents, attributes) { 485 var el, mp, attr, points; 486 487 // we need 2 points 488 points = Type.providePoints(board, parents, attributes, "point"); 489 if (points === false || points.length !== 2) { 490 throw new Error( 491 "JSXGraph: Can't create Semicircle with parent types '" + 492 typeof parents[0] + 493 "' and '" + 494 typeof parents[1] + 495 "'." + 496 "\nPossible parent types: [point,point]" 497 ); 498 } 499 500 attr = Type.copyAttributes(attributes, board.options, "semicircle", "center"); 501 mp = board.create("midpoint", points, attr); 502 mp.dump = false; 503 504 attr = Type.copyAttributes(attributes, board.options, "semicircle"); 505 el = board.create("arc", [mp, points[1], points[0]], attr); 506 el.elType = "semicircle"; 507 el.setParents([points[0].id, points[1].id]); 508 el.subs = { 509 midpoint: mp 510 }; 511 el.inherits.push(mp); 512 513 /** 514 * The midpoint of the two defining points. 515 * @memberOf Semicircle.prototype 516 * @name midpoint 517 * @type Midpoint 518 */ 519 el.midpoint = el.center = mp; 520 521 return el; 522 }; 523 524 JXG.registerElement("semicircle", JXG.createSemicircle); 525 526 /** 527 * @class A partial circum circle through three points. 528 * @pseudo 529 * @name CircumcircleArc 530 * @augments Arc 531 * @constructor 532 * @type Arc 533 * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown. 534 * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be a composition of an arc of the circumcircle of 535 * <tt>p1</tt>, <tt>p2</tt>, and <tt>p3</tt> and the midpoint of the circumcircle of the three points. The arc is drawn 536 * counter-clockwise from <tt>p1</tt> over <tt>p2</tt> to <tt>p3</tt>. 537 * @example 538 * // Create a circum circle arc out of three free points 539 * var p1 = board.create('point', [2.0, 2.0]); 540 * var p2 = board.create('point', [1.0, 0.5]); 541 * var p3 = board.create('point', [3.5, 1.0]); 542 * 543 * var a = board.create('circumcirclearc', [p1, p2, p3]); 544 * </pre><div class="jxgbox" id="JXG87125fd4-823a-41c1-88ef-d1a1369504e3" style="width: 300px; height: 300px;"></div> 545 * <script type="text/javascript"> 546 * (function () { 547 * var board = JXG.JSXGraph.initBoard('JXG87125fd4-823a-41c1-88ef-d1a1369504e3', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}), 548 * p1 = board.create('point', [2.0, 2.0]), 549 * p2 = board.create('point', [1.0, 0.5]), 550 * p3 = board.create('point', [3.5, 1.0]), 551 * 552 * cca = board.create('circumcirclearc', [p1, p2, p3]); 553 * })(); 554 * </script><pre> 555 */ 556 JXG.createCircumcircleArc = function (board, parents, attributes) { 557 var el, mp, attr, points; 558 559 // We need three points 560 points = Type.providePoints(board, parents, attributes, "point"); 561 if (points === false || points.length !== 3) { 562 throw new Error( 563 "JSXGraph: create Circumcircle Arc with parent types '" + 564 typeof parents[0] + 565 "' and '" + 566 typeof parents[1] + 567 "' and '" + 568 typeof parents[2] + 569 "'." + 570 "\nPossible parent types: [point,point,point]" 571 ); 572 } 573 574 attr = Type.copyAttributes(attributes, board.options, "circumcirclearc", "center"); 575 mp = board.create("circumcenter", points, attr); 576 mp.dump = false; 577 578 attr = Type.copyAttributes(attributes, board.options, "circumcirclearc"); 579 attr.usedirection = true; 580 el = board.create("arc", [mp, points[0], points[2], points[1]], attr); 581 582 el.elType = "circumcirclearc"; 583 el.setParents([points[0].id, points[1].id, points[2].id]); 584 el.subs = { 585 center: mp 586 }; 587 el.inherits.push(mp); 588 589 /** 590 * The midpoint of the circumcircle of the three points defining the circumcircle arc. 591 * @memberOf CircumcircleArc.prototype 592 * @name center 593 * @type Circumcenter 594 */ 595 el.center = mp; 596 597 return el; 598 }; 599 600 JXG.registerElement("circumcirclearc", JXG.createCircumcircleArc); 601 602 /** 603 * @class A minor arc given by three points is that part of the circumference of a circle having 604 * measure at most 180 degrees (pi radians). It is defined by a center, one point that 605 * defines the radius, and a third point that defines the angle of the arc. 606 * @pseudo 607 * @name MinorArc 608 * @augments Curve 609 * @constructor 610 * @type JXG.Curve 611 * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown. 612 * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Minor arc is an arc of a circle around p1 having measure less than or equal to 613 * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3. 614 * @example 615 * // Create an arc out of three free points 616 * var p1 = board.create('point', [2.0, 2.0]); 617 * var p2 = board.create('point', [1.0, 0.5]); 618 * var p3 = board.create('point', [3.5, 1.0]); 619 * 620 * var a = board.create('arc', [p1, p2, p3]); 621 * </pre><div class="jxgbox" id="JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f" style="width: 300px; height: 300px;"></div> 622 * <script type="text/javascript"> 623 * (function () { 624 * var board = JXG.JSXGraph.initBoard('JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}), 625 * p1 = board.create('point', [2.0, 2.0]), 626 * p2 = board.create('point', [1.0, 0.5]), 627 * p3 = board.create('point', [3.5, 1.0]), 628 * 629 * a = board.create('minorarc', [p1, p2, p3]); 630 * })(); 631 * </script><pre> 632 */ 633 634 JXG.createMinorArc = function (board, parents, attributes) { 635 attributes.selection = "minor"; 636 return JXG.createArc(board, parents, attributes); 637 }; 638 639 JXG.registerElement("minorarc", JXG.createMinorArc); 640 641 /** 642 * @class A major arc given by three points is that part of the circumference of a circle having 643 * measure at least 180 degrees (pi radians). It is defined by a center, one point that 644 * defines the radius, and a third point that defines the angle of the arc. 645 * @pseudo 646 * @name MajorArc 647 * @augments Curve 648 * @constructor 649 * @type JXG.Curve 650 * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown. 651 * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Major arc is an arc of a circle around p1 having measure greater than or equal to 652 * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3. 653 * @example 654 * // Create an arc out of three free points 655 * var p1 = board.create('point', [2.0, 2.0]); 656 * var p2 = board.create('point', [1.0, 0.5]); 657 * var p3 = board.create('point', [3.5, 1.0]); 658 * 659 * var a = board.create('majorarc', [p1, p2, p3]); 660 * </pre><div class="jxgbox" id="JXG17a10d38-5629-40a4-b150-f41806edee9f" style="width: 300px; height: 300px;"></div> 661 * <script type="text/javascript"> 662 * (function () { 663 * var board = JXG.JSXGraph.initBoard('JXG17a10d38-5629-40a4-b150-f41806edee9f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}), 664 * p1 = board.create('point', [2.0, 2.0]), 665 * p2 = board.create('point', [1.0, 0.5]), 666 * p3 = board.create('point', [3.5, 1.0]), 667 * 668 * a = board.create('majorarc', [p1, p2, p3]); 669 * })(); 670 * </script><pre> 671 */ 672 JXG.createMajorArc = function (board, parents, attributes) { 673 attributes.selection = "major"; 674 return JXG.createArc(board, parents, attributes); 675 }; 676 677 JXG.registerElement("majorarc", JXG.createMajorArc); 678