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